mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-09 23:58:06 -05:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4be9389dcb | ||
|
|
2fde07b9be | ||
|
|
70c5f4bfaf | ||
|
|
0a2e67878a | ||
|
|
c381c916f3 | ||
|
|
9999072620 | ||
|
|
34238e9f18 | ||
|
|
a1c493b009 | ||
|
|
e7f9805fd4 | ||
|
|
8956d4caa1 | ||
|
|
b85911dee3 | ||
|
|
2d1a961c1b | ||
|
|
195cbfb9e5 | ||
|
|
96a3153c23 | ||
|
|
64238fc80e | ||
|
|
afaad713ff | ||
|
|
f48b6f1651 | ||
|
|
34ed989725 | ||
|
|
b52e642c01 | ||
|
|
098345aace | ||
|
|
caa1a55d17 | ||
|
|
fee43f3c11 | ||
|
|
fad60747d5 | ||
|
|
5ceef2d4de | ||
|
|
6635caf12e | ||
|
|
e051360ea2 | ||
|
|
6bb74c5abf | ||
|
|
a79057070c | ||
|
|
12fc5b76d8 | ||
|
|
ad5892391d | ||
|
|
df43a3560a | ||
|
|
9aa17eec07 | ||
|
|
45cc668683 | ||
|
|
19045a483d | ||
|
|
f618b88f91 | ||
|
|
81cb5b00f4 | ||
|
|
54fb582269 | ||
|
|
44f7325a91 | ||
|
|
4ab54943ad | ||
|
|
45245df16a | ||
|
|
63ea6533de | ||
|
|
aedc9b7696 | ||
|
|
28248e3167 | ||
|
|
612e30258c | ||
|
|
76c888268b | ||
|
|
07f2712a22 | ||
|
|
75e8555035 | ||
|
|
a823e510f3 | ||
|
|
2d53cf4424 | ||
|
|
e91b8ee0ba | ||
|
|
eced9b015b | ||
|
|
dbc3c4f08f | ||
|
|
0d56ae2705 | ||
|
|
c1e4031e3b | ||
|
|
964ae53e5b |
46
.travis.yml
46
.travis.yml
@@ -1,8 +1,6 @@
|
||||
language: ruby
|
||||
|
||||
rvm:
|
||||
- 2.1.10
|
||||
- 2.2.10
|
||||
- 2.3.8
|
||||
- 2.4.5
|
||||
- 2.5.3
|
||||
@@ -11,44 +9,17 @@ rvm:
|
||||
|
||||
gemfile:
|
||||
- Gemfile
|
||||
- gemfiles/Gemfile.rails-6.0-beta
|
||||
- gemfiles/Gemfile.rails-6.0-stable
|
||||
- gemfiles/Gemfile.rails-5.2-stable
|
||||
- gemfiles/Gemfile.rails-5.0-stable
|
||||
- gemfiles/Gemfile.rails-4.2-stable
|
||||
- gemfiles/Gemfile.rails-4.1-stable
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- rvm: 2.1.10
|
||||
gemfile: Gemfile
|
||||
- rvm: 2.1.10
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-beta
|
||||
- rvm: 2.1.10
|
||||
gemfile: gemfiles/Gemfile.rails-5.2-stable
|
||||
- rvm: 2.1.10
|
||||
gemfile: gemfiles/Gemfile.rails-5.0-stable
|
||||
- rvm: 2.2.10
|
||||
gemfile: Gemfile
|
||||
- rvm: 2.2.10
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-beta
|
||||
- rvm: 2.2.10
|
||||
gemfile: gemfiles/Gemfile.rails-5.2-stable
|
||||
- rvm: 2.3.8
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-beta
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-stable
|
||||
- rvm: 2.4.5
|
||||
gemfile: gemfiles/Gemfile.rails-4.1-stable
|
||||
- rvm: 2.4.5
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-beta
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-stable
|
||||
- rvm: 2.5.3
|
||||
gemfile: gemfiles/Gemfile.rails-4.1-stable
|
||||
- rvm: 2.6.0
|
||||
gemfile: gemfiles/Gemfile.rails-4.1-stable
|
||||
- rvm: 2.6.0
|
||||
gemfile: gemfiles/Gemfile.rails-4.2-stable
|
||||
- rvm: ruby-head
|
||||
gemfile: gemfiles/Gemfile.rails-4.1-stable
|
||||
- rvm: ruby-head
|
||||
gemfile: gemfiles/Gemfile.rails-4.2-stable
|
||||
- env: DEVISE_ORM=mongoid
|
||||
gemfile: Gemfile
|
||||
- env: DEVISE_ORM=mongoid
|
||||
@@ -56,16 +27,14 @@ matrix:
|
||||
- env: DEVISE_ORM=mongoid
|
||||
gemfile: gemfiles/Gemfile.rails-5.2-stable
|
||||
- env: DEVISE_ORM=mongoid
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-beta
|
||||
gemfile: gemfiles/Gemfile.rails-6.0-stable
|
||||
allow_failures:
|
||||
- rvm: ruby-head
|
||||
- gemfile: gemfiles/Gemfile.rails-6.0-beta
|
||||
- gemfile: gemfiles/Gemfile.rails-6.0-stable
|
||||
|
||||
services:
|
||||
- mongodb
|
||||
|
||||
sudo: false
|
||||
|
||||
cache: bundler
|
||||
|
||||
env:
|
||||
@@ -73,10 +42,7 @@ env:
|
||||
- DEVISE_ORM=active_record
|
||||
- DEVISE_ORM=mongoid
|
||||
|
||||
before_install:
|
||||
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
||||
- gem install bundler -v '< 2'
|
||||
- "rm ${BUNDLE_GEMFILE}.lock"
|
||||
before_install: "rm ${BUNDLE_GEMFILE}.lock"
|
||||
|
||||
before_script: "bundle update"
|
||||
|
||||
|
||||
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,4 +1,34 @@
|
||||
### 5.0.0-rc
|
||||
|
||||
* enhancements
|
||||
* Suport multiple translations according to unlock strategy (by @sivagollapalli)
|
||||
* Use `ActiveSupport::SecurityUtils.secure_compare` inside `Devise.secure_compare` (by @shrirambalakrishnan)
|
||||
* Update trackable fields only in a database sign in (by @waiting-for-dev)
|
||||
|
||||
* deprecations
|
||||
* Remove Rails 4, Ruby 2.1 and Ruby 2.2 support (by @feliperenan)
|
||||
|
||||
### Unreleased
|
||||
* enhancements
|
||||
* Increase default stretches to 12 (by @sergey-alekseev)
|
||||
|
||||
### 4.7.1 - 2019-09-06
|
||||
|
||||
* bug fixes
|
||||
* Fix an edge case where records with a blank `confirmation_token` could be confirmed (by @tegon)
|
||||
* Fix typo inside `update_needs_confirmation` i18n key (by @lslm)
|
||||
|
||||
### 4.7.0 - 2019-08-19
|
||||
|
||||
* enhancements
|
||||
* Support Rails 6.0
|
||||
* Update CI to rails 6.0.0.beta3 (by @tunnes)
|
||||
* refactor method name to be more consistent (by @saiqulhaq)
|
||||
* Fix rails 6.0.rc1 email uniqueness validation deprecation warning (by @Vasfed)
|
||||
|
||||
* bug fixes
|
||||
* Add `autocomplete="new-password"` to `password_confirmation` fields (by @ferrl)
|
||||
* Fix rails_51_and_up? method for Rails 6.rc1 (by @igorkasyanchuk)
|
||||
|
||||
### 4.6.2 - 2019-03-26
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ GIT
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 5.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
|
||||
@@ -62,7 +62,7 @@ GEM
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
arel (9.0.0)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt (3.1.13)
|
||||
builder (3.2.3)
|
||||
concurrent-ruby (1.0.5)
|
||||
crass (1.0.4)
|
||||
@@ -201,4 +201,4 @@ DEPENDENCIES
|
||||
webrat (= 0.7.3)
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
1.17.3
|
||||
|
||||
20
README.md
20
README.md
@@ -137,17 +137,17 @@ Please note that the command output will show the variable value being used.
|
||||
### BUNDLE_GEMFILE
|
||||
We can use this variable to tell bundler what Gemfile it should use (instead of the one in the current directory).
|
||||
Inside the [gemfiles](https://github.com/plataformatec/devise/tree/master/gemfiles) directory, we have one for each version of Rails we support. When you send us a pull request, it may happen that the test suite breaks on Travis using some of them. If that's the case, you can simulate the same environment using the `BUNDLE_GEMFILE` variable.
|
||||
For example, if the tests broke using Ruby 2.4.2 and Rails 4.1, you can do the following:
|
||||
For example, if the tests broke using Ruby 2.5.0 and Rails 5.0, you can do the following:
|
||||
```bash
|
||||
rbenv shell 2.4.2 # or rvm use 2.4.2
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.1-stable bundle install
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.1-stable bin/test
|
||||
rbenv shell 2.5.0 # or rvm use 2.5.0
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-5.0-stable bundle install
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-5.0-stable bin/test
|
||||
```
|
||||
|
||||
You can also combine both of them if the tests broke for Mongoid:
|
||||
```bash
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.1-stable bundle install
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.1-stable DEVISE_ORM=mongoid bin/test
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-5.0-stable bundle install
|
||||
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-5.0-stable DEVISE_ORM=mongoid bin/test
|
||||
```
|
||||
|
||||
### Running tests
|
||||
@@ -174,13 +174,13 @@ If you are building your first Rails application, we recommend you *do not* use
|
||||
|
||||
* Michael Hartl's online book: https://www.railstutorial.org/book/modeling_users
|
||||
* Ryan Bates' Railscast: http://railscasts.com/episodes/250-authentication-from-scratch
|
||||
* Codecademy's Ruby on Rails: Authentication and Authorization: http://www.codecademy.com/en/learn/rails-auth
|
||||
* Codecademy's Ruby on Rails: Authentication and Authorization: https://www.codecademy.com/learn/rails-auth
|
||||
|
||||
Once you have solidified your understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :smiley:
|
||||
|
||||
## Getting started
|
||||
|
||||
Devise 4.0 works with Rails 4.1 onwards. Add the following line to your Gemfile:
|
||||
Devise 5.0 works with Rails 5.0 onwards. Add the following line to your Gemfile:
|
||||
|
||||
```ruby
|
||||
gem 'devise'
|
||||
@@ -270,7 +270,7 @@ member_session
|
||||
The Devise method in your models also accepts some options to configure its modules. For example, you can choose the cost of the hashing algorithm with:
|
||||
|
||||
```ruby
|
||||
devise :database_authenticatable, :registerable, :confirmable, :recoverable, stretches: 12
|
||||
devise :database_authenticatable, :registerable, :confirmable, :recoverable, stretches: 13
|
||||
```
|
||||
|
||||
Besides `:stretches`, you can define `:pepper`, `:encryptor`, `:confirm_within`, `:remember_for`, `:timeout_in`, `:unlock_in` among other options. For more details, see the initializer file that was created when you invoked the "devise:install" generator described above. This file is usually located at `/config/initializers/devise.rb`.
|
||||
@@ -732,6 +732,6 @@ https://github.com/plataformatec/devise/graphs/contributors
|
||||
|
||||
## License
|
||||
|
||||
MIT License. Copyright 2009-2018 Plataformatec. http://plataformatec.com.br
|
||||
MIT License. Copyright 2009-2019 Plataformatec. http://plataformatec.com.br
|
||||
|
||||
You are not granted rights or licenses to the trademarks of Plataformatec, including without limitation the Devise name or logo.
|
||||
|
||||
@@ -47,7 +47,12 @@ class Devise::PasswordsController < DeviseController
|
||||
respond_with resource, location: after_resetting_password_path_for(resource)
|
||||
else
|
||||
set_minimum_password_length
|
||||
respond_with resource
|
||||
|
||||
if expired_token_error?(resource)
|
||||
redirect_to new_password_path(resource_name), alert: t('devise.passwords.expired_token')
|
||||
else
|
||||
respond_with resource
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -80,4 +85,9 @@ class Devise::PasswordsController < DeviseController
|
||||
def translation_scope
|
||||
'devise.passwords'
|
||||
end
|
||||
|
||||
private
|
||||
def expired_token_error?(resource)
|
||||
resource.errors.details[:reset_password_token].any? { |error| error[:error] == :expired }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,7 +28,7 @@ class Devise::SessionsController < DeviseController
|
||||
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
|
||||
set_flash_message! :notice, :signed_out if signed_out
|
||||
yield if block_given?
|
||||
respond_to_on_destroy
|
||||
respond_to_on_destroy(status: :no_content)
|
||||
end
|
||||
|
||||
protected
|
||||
@@ -62,7 +62,7 @@ class Devise::SessionsController < DeviseController
|
||||
if all_signed_out?
|
||||
set_flash_message! :notice, :already_signed_out
|
||||
|
||||
respond_to_on_destroy
|
||||
respond_to_on_destroy(status: :unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -72,11 +72,11 @@ class Devise::SessionsController < DeviseController
|
||||
users.all?(&:blank?)
|
||||
end
|
||||
|
||||
def respond_to_on_destroy
|
||||
def respond_to_on_destroy(status:)
|
||||
# We actually need to hardcode this as Rails default responder doesn't
|
||||
# support returning empty response on GET request
|
||||
respond_to do |format|
|
||||
format.all { head :no_content }
|
||||
format.all { head status }
|
||||
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :password_confirmation, "Confirm new password" %><br />
|
||||
<%= f.password_field :password_confirmation, autocomplete: "off" %>
|
||||
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
|
||||
@@ -10,7 +10,11 @@ en:
|
||||
already_authenticated: "You are already signed in."
|
||||
inactive: "Your account is not activated yet."
|
||||
invalid: "Invalid %{authentication_keys} or password."
|
||||
locked: "Your account is locked."
|
||||
locked:
|
||||
none: "Your account is locked."
|
||||
email: "Your account is locked. An email has been sent with instructions on how to unlock your account."
|
||||
time: "Your account is locked. Your account will become available after a certain amount of time."
|
||||
both: "Your account is locked. An email has been sent with instructions on how to unlock your account, or wait a certain amount of time and try again."
|
||||
last_attempt: "You have one more attempt before your account is locked."
|
||||
not_found_in_database: "Invalid %{authentication_keys} or password."
|
||||
timeout: "Your session expired. Please sign in again to continue."
|
||||
@@ -36,13 +40,14 @@ en:
|
||||
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
||||
updated: "Your password has been changed successfully. You are now signed in."
|
||||
updated_not_active: "Your password has been changed successfully."
|
||||
expired_token: "The password recovery link expired. Please request a new one."
|
||||
registrations:
|
||||
destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
|
||||
signed_up: "Welcome! You have signed up successfully."
|
||||
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
|
||||
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
|
||||
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
|
||||
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
|
||||
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
|
||||
updated: "Your account has been updated successfully."
|
||||
updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again"
|
||||
sessions:
|
||||
|
||||
@@ -17,11 +17,11 @@ Gem::Specification.new do |s|
|
||||
|
||||
s.files = Dir["{app,config,lib}/**/*", "CHANGELOG.md", "MIT-LICENSE", "README.md"]
|
||||
s.require_paths = ["lib"]
|
||||
s.required_ruby_version = '>= 2.1.0'
|
||||
s.required_ruby_version = '>= 2.3.0'
|
||||
|
||||
s.add_dependency("warden", "~> 1.2.3")
|
||||
s.add_dependency("orm_adapter", "~> 0.1")
|
||||
s.add_dependency("bcrypt", "~> 3.0")
|
||||
s.add_dependency("railties", ">= 4.1.0", "< 6.0")
|
||||
s.add_dependency("railties", ">= 5.0")
|
||||
s.add_dependency("responders")
|
||||
end
|
||||
|
||||
@@ -21,10 +21,10 @@ GIT
|
||||
PATH
|
||||
remote: ..
|
||||
specs:
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
|
||||
@@ -54,7 +54,7 @@ GEM
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 1.1)
|
||||
arel (5.0.1.20140414130214)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt (3.1.13)
|
||||
bson (3.2.6)
|
||||
builder (3.2.3)
|
||||
concurrent-ruby (1.0.5)
|
||||
|
||||
@@ -57,10 +57,10 @@ GIT
|
||||
PATH
|
||||
remote: ..
|
||||
specs:
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
|
||||
@@ -68,7 +68,7 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
arel (6.0.4)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt (3.1.13)
|
||||
bson (3.2.6)
|
||||
builder (3.2.3)
|
||||
concurrent-ruby (1.0.5)
|
||||
|
||||
@@ -21,7 +21,6 @@ group :test do
|
||||
gem "timecop"
|
||||
gem "webrat", "0.7.3", require: false
|
||||
gem "mocha", "~> 1.1", require: false
|
||||
gem 'test_after_commit', require: false
|
||||
end
|
||||
|
||||
platforms :ruby do
|
||||
|
||||
@@ -10,10 +10,10 @@ GIT
|
||||
PATH
|
||||
remote: ..
|
||||
specs:
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 5.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
|
||||
@@ -58,7 +58,7 @@ GEM
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
arel (7.1.4)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt (3.1.13)
|
||||
builder (3.2.3)
|
||||
concurrent-ruby (1.0.5)
|
||||
erubis (2.7.0)
|
||||
@@ -153,8 +153,6 @@ GEM
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.3.13)
|
||||
test_after_commit (1.1.0)
|
||||
activerecord (>= 3.2)
|
||||
thor (0.19.4)
|
||||
thread_safe (0.3.6)
|
||||
timecop (0.8.1)
|
||||
@@ -191,4 +189,4 @@ DEPENDENCIES
|
||||
webrat (= 0.7.3)
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
1.17.3
|
||||
|
||||
@@ -19,7 +19,6 @@ group :test do
|
||||
gem "timecop"
|
||||
gem "webrat", "0.7.3", require: false
|
||||
gem "mocha", "~> 1.1", require: false
|
||||
gem 'test_after_commit', require: false
|
||||
end
|
||||
|
||||
platforms :ruby do
|
||||
|
||||
@@ -10,10 +10,10 @@ GIT
|
||||
PATH
|
||||
remote: ..
|
||||
specs:
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 5.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
|
||||
@@ -62,7 +62,7 @@ GEM
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
arel (9.0.0)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt (3.1.13)
|
||||
builder (3.2.3)
|
||||
concurrent-ruby (1.0.5)
|
||||
crass (1.0.4)
|
||||
@@ -162,8 +162,6 @@ GEM
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.3.13)
|
||||
test_after_commit (1.1.0)
|
||||
activerecord (>= 3.2)
|
||||
thor (0.20.0)
|
||||
thread_safe (0.3.6)
|
||||
timecop (0.9.1)
|
||||
@@ -200,4 +198,4 @@ DEPENDENCIES
|
||||
webrat (= 0.7.3)
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
1.17.3
|
||||
|
||||
@@ -2,7 +2,7 @@ source "https://rubygems.org"
|
||||
|
||||
gemspec path: ".."
|
||||
|
||||
gem "rails", '6.0.0.beta1'
|
||||
gem "rails", '~> 6.0.0'
|
||||
gem "omniauth"
|
||||
gem "omniauth-oauth2"
|
||||
gem "rdoc"
|
||||
@@ -11,7 +11,7 @@ gem "activemodel-serializers-xml", github: "rails/activemodel-serializers-xml"
|
||||
|
||||
gem "rails-controller-testing"
|
||||
|
||||
gem "responders", "~> 2.4"
|
||||
gem "responders", "~> 3.0"
|
||||
|
||||
group :test do
|
||||
gem "omniauth-facebook"
|
||||
@@ -23,5 +23,5 @@ group :test do
|
||||
end
|
||||
|
||||
platforms :ruby do
|
||||
gem "sqlite3", "~> 1.3.6"
|
||||
gem "sqlite3", "~> 1.4"
|
||||
end
|
||||
@@ -1,81 +1,83 @@
|
||||
GIT
|
||||
remote: git://github.com/rails/activemodel-serializers-xml.git
|
||||
revision: f744aeca2747ed3134e492249c4ee39b548efdf6
|
||||
revision: 93689638c28525acc65afb638fce866826532641
|
||||
specs:
|
||||
activemodel-serializers-xml (1.0.2)
|
||||
activemodel (> 5.x)
|
||||
activesupport (> 5.x)
|
||||
activemodel (>= 5.0.0.a)
|
||||
activesupport (>= 5.0.0.a)
|
||||
builder (~> 3.1)
|
||||
|
||||
PATH
|
||||
remote: ..
|
||||
specs:
|
||||
devise (4.6.2)
|
||||
devise (4.7.1)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 6.0)
|
||||
railties (>= 5.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
actioncable (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
activejob (= 6.0.0.beta1)
|
||||
activerecord (= 6.0.0.beta1)
|
||||
activestorage (= 6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
actionmailbox (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
activestorage (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
mail (>= 2.7.1)
|
||||
actionmailer (6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
actionview (= 6.0.0.beta1)
|
||||
activejob (= 6.0.0.beta1)
|
||||
actionmailer (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
actionview (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (6.0.0.beta1)
|
||||
actionview (= 6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
actionpack (6.0.0)
|
||||
actionview (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
rack (~> 2.0)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actiontext (6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
activerecord (= 6.0.0.beta1)
|
||||
activestorage (= 6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
activestorage (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
actionview (6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
activejob (6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
activejob (6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
activerecord (6.0.0.beta1)
|
||||
activemodel (= 6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
activestorage (6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
activerecord (= 6.0.0.beta1)
|
||||
activemodel (6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
activerecord (6.0.0)
|
||||
activemodel (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
activestorage (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
marcel (~> 0.3.1)
|
||||
activesupport (6.0.0.beta1)
|
||||
activesupport (6.0.0)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
bcrypt (3.1.12)
|
||||
zeitwerk (~> 2.1, >= 2.1.8)
|
||||
bcrypt (3.1.13)
|
||||
builder (3.2.3)
|
||||
concurrent-ruby (1.1.4)
|
||||
concurrent-ruby (1.1.5)
|
||||
crass (1.0.4)
|
||||
erubi (1.8.0)
|
||||
faraday (0.15.4)
|
||||
@@ -83,9 +85,9 @@ GEM
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
hashie (3.6.0)
|
||||
i18n (1.5.2)
|
||||
i18n (1.6.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jwt (2.1.0)
|
||||
jwt (2.2.1)
|
||||
loofah (2.2.3)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
@@ -96,16 +98,16 @@ GEM
|
||||
metaclass (0.0.4)
|
||||
method_source (0.9.2)
|
||||
mimemagic (0.3.3)
|
||||
mini_mime (1.0.1)
|
||||
mini_mime (1.0.2)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.11.3)
|
||||
mocha (1.8.0)
|
||||
mocha (1.9.0)
|
||||
metaclass (~> 0.0.1)
|
||||
multi_json (1.13.1)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
nio4r (2.3.1)
|
||||
nokogiri (1.10.1)
|
||||
multipart-post (2.1.1)
|
||||
nio4r (2.4.0)
|
||||
nokogiri (1.10.4)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
oauth2 (1.4.1)
|
||||
faraday (>= 0.8, < 0.16.0)
|
||||
@@ -125,26 +127,26 @@ GEM
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
orm_adapter (0.5.0)
|
||||
rack (2.0.6)
|
||||
rack (2.0.7)
|
||||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (6.0.0.beta1)
|
||||
actioncable (= 6.0.0.beta1)
|
||||
actionmailbox (= 6.0.0.beta1)
|
||||
actionmailer (= 6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
actiontext (= 6.0.0.beta1)
|
||||
actionview (= 6.0.0.beta1)
|
||||
activejob (= 6.0.0.beta1)
|
||||
activemodel (= 6.0.0.beta1)
|
||||
activerecord (= 6.0.0.beta1)
|
||||
activestorage (= 6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
rails (6.0.0)
|
||||
actioncable (= 6.0.0)
|
||||
actionmailbox (= 6.0.0)
|
||||
actionmailer (= 6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
actiontext (= 6.0.0)
|
||||
actionview (= 6.0.0)
|
||||
activejob (= 6.0.0)
|
||||
activemodel (= 6.0.0)
|
||||
activerecord (= 6.0.0)
|
||||
activestorage (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 6.0.0.beta1)
|
||||
railties (= 6.0.0)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.4)
|
||||
actionpack (>= 5.0.1.x)
|
||||
@@ -153,19 +155,19 @@ GEM
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.0.4)
|
||||
rails-html-sanitizer (1.2.0)
|
||||
loofah (~> 2.2, >= 2.2.2)
|
||||
railties (6.0.0.beta1)
|
||||
actionpack (= 6.0.0.beta1)
|
||||
activesupport (= 6.0.0.beta1)
|
||||
railties (6.0.0)
|
||||
actionpack (= 6.0.0)
|
||||
activesupport (= 6.0.0)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.20.3, < 2.0)
|
||||
rake (12.3.2)
|
||||
rake (12.3.3)
|
||||
rdoc (6.1.1)
|
||||
responders (2.4.1)
|
||||
actionpack (>= 4.2.0, < 6.0)
|
||||
railties (>= 4.2.0, < 6.0)
|
||||
responders (3.0.0)
|
||||
actionpack (>= 5.0)
|
||||
railties (>= 5.0)
|
||||
ruby-openid (2.7.0)
|
||||
sprockets (3.7.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
@@ -174,7 +176,7 @@ GEM
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.3.13)
|
||||
sqlite3 (1.4.1)
|
||||
test_after_commit (1.1.0)
|
||||
activerecord (>= 3.2)
|
||||
thor (0.20.3)
|
||||
@@ -188,9 +190,10 @@ GEM
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
websocket-driver (0.7.0)
|
||||
websocket-driver (0.7.1)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
websocket-extensions (0.1.4)
|
||||
zeitwerk (2.1.9)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@@ -203,14 +206,14 @@ DEPENDENCIES
|
||||
omniauth-facebook
|
||||
omniauth-oauth2
|
||||
omniauth-openid
|
||||
rails (= 6.0.0.beta1)
|
||||
rails (~> 6.0.0)
|
||||
rails-controller-testing
|
||||
rdoc
|
||||
responders (~> 2.4)
|
||||
sqlite3 (~> 1.3.6)
|
||||
responders (~> 3.0)
|
||||
sqlite3 (~> 1.4)
|
||||
test_after_commit
|
||||
timecop
|
||||
webrat (= 0.7.3)
|
||||
|
||||
BUNDLED WITH
|
||||
1.17.1
|
||||
1.17.3
|
||||
10
lib/devise.rb
Executable file → Normal file
10
lib/devise.rb
Executable file → Normal file
@@ -71,7 +71,7 @@ module Devise
|
||||
|
||||
# The number of times to hash the password.
|
||||
mattr_accessor :stretches
|
||||
@@stretches = 11
|
||||
@@stretches = 12
|
||||
|
||||
# The default key used when authenticating over http auth.
|
||||
mattr_accessor :http_authentication_key
|
||||
@@ -502,12 +502,8 @@ module Devise
|
||||
|
||||
# constant-time comparison algorithm to prevent timing attacks
|
||||
def self.secure_compare(a, b)
|
||||
return false if a.blank? || b.blank? || a.bytesize != b.bytesize
|
||||
l = a.unpack "C#{a.bytesize}"
|
||||
|
||||
res = 0
|
||||
b.each_byte { |byte| res |= byte ^ l.shift }
|
||||
res == 0
|
||||
return false if a.nil? || b.nil?
|
||||
ActiveSupport::SecurityUtils.secure_compare(a, b)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ module Devise
|
||||
|
||||
def #{group_name}_signed_in?
|
||||
#{mappings}.any? do |mapping|
|
||||
warden.authenticate?(scope: mapping)
|
||||
warden.authenticated?(scope: mapping)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -119,7 +119,7 @@ module Devise
|
||||
end
|
||||
|
||||
def #{mapping}_signed_in?
|
||||
!!current_#{mapping}
|
||||
!!(@current_#{mapping} || warden.authenticated?(scope: :#{mapping}))
|
||||
end
|
||||
|
||||
def current_#{mapping}
|
||||
|
||||
@@ -12,7 +12,7 @@ module Devise
|
||||
# authentication hooks, you can directly call `warden.authenticated?(scope: scope)`
|
||||
def signed_in?(scope=nil)
|
||||
[scope || Devise.mappings.keys].flatten.any? do |_scope|
|
||||
warden.authenticate?(scope: _scope)
|
||||
warden.authenticated?(scope: _scope)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -51,6 +51,7 @@ module Devise
|
||||
true
|
||||
else
|
||||
warden.set_user(resource, options.merge!(scope: scope))
|
||||
resource.update_tracked_fields!(warden.request) if resource.respond_to?(:update_tracked_fields!)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -103,11 +103,14 @@ module Devise
|
||||
options[:scope] = "devise.failure"
|
||||
options[:default] = [message]
|
||||
auth_keys = scope_class.authentication_keys
|
||||
keys = (auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys).map { |key| scope_class.human_attribute_name(key) }
|
||||
keys = (auth_keys.respond_to?(:keys) ? auth_keys.keys : auth_keys).map { |key| scope_class.human_attribute_name(key).downcase }
|
||||
options[:authentication_keys] = keys.join(I18n.translate(:"support.array.words_connector"))
|
||||
options = i18n_options(options)
|
||||
translated_message = I18n.t(:"#{scope}.#{message}", options)
|
||||
|
||||
I18n.t(:"#{scope}.#{message}", options)
|
||||
# only call `#humanize` when the message is `:invalid` to ensure the original format
|
||||
# of other messages - like `:does_not_exist` - is kept.
|
||||
message == :invalid ? translated_message.humanize : translated_message
|
||||
else
|
||||
message.to_s
|
||||
end
|
||||
@@ -153,7 +156,7 @@ module Devise
|
||||
# We need to add the rootpath to `script_name` manually for applications that use a Rails
|
||||
# version lower than 5.1. Otherwise, it is going to generate a wrong path for Engines
|
||||
# that use Devise. Remove it when the support of Rails 5.0 is droped.
|
||||
elsif root_path_defined?(context) && rails_5_and_down?
|
||||
elsif root_path_defined?(context) && !rails_51_and_up?
|
||||
rootpath = context.routes.url_helpers.root_path
|
||||
opts[:script_name] = rootpath.chomp('/') if rootpath.length > 1
|
||||
end
|
||||
@@ -278,14 +281,8 @@ module Devise
|
||||
defined?(context.routes) && context.routes.url_helpers.respond_to?(:root_path)
|
||||
end
|
||||
|
||||
def rails_5_and_down?
|
||||
return false if rails_5_up?
|
||||
|
||||
Rails::VERSION::MAJOR >= 4
|
||||
end
|
||||
|
||||
def rails_5_up?
|
||||
Rails::VERSION::MAJOR >= 5 && Rails::VERSION::MINOR > 0
|
||||
def rails_51_and_up?
|
||||
Rails.gem_version >= Gem::Version.new("5.1")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# After each sign in, update sign in time, sign in count and sign in IP.
|
||||
# This is only triggered when the user is explicitly set (with set_user)
|
||||
# and on authentication. Retrieving the user from session (:fetch) does
|
||||
# not trigger it.
|
||||
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
|
||||
if record.respond_to?(:update_tracked_fields!) && warden.authenticated?(options[:scope]) && !warden.request.env['devise.skip_trackable']
|
||||
record.update_tracked_fields!(warden.request)
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'active_model/version'
|
||||
require 'devise/hooks/activatable'
|
||||
require 'devise/hooks/csrf_cleaner'
|
||||
|
||||
@@ -183,11 +182,8 @@ module Devise
|
||||
# # Deliver later with Active Job's `deliver_later`
|
||||
# if message.respond_to?(:deliver_later)
|
||||
# message.deliver_later
|
||||
# # Remove once we move to Rails 4.2+ only, as `deliver` is deprecated.
|
||||
# elsif message.respond_to?(:deliver_now)
|
||||
# message.deliver_now
|
||||
# else
|
||||
# message.deliver
|
||||
# message.deliver_now
|
||||
# end
|
||||
# end
|
||||
#
|
||||
@@ -195,12 +191,7 @@ module Devise
|
||||
#
|
||||
def send_devise_notification(notification, *args)
|
||||
message = devise_mailer.send(notification, self, *args)
|
||||
# Remove once we move to Rails 4.2+ only.
|
||||
if message.respond_to?(:deliver_now)
|
||||
message.deliver_now
|
||||
else
|
||||
message.deliver
|
||||
end
|
||||
message.deliver_now
|
||||
end
|
||||
|
||||
def downcase_keys
|
||||
|
||||
@@ -348,7 +348,19 @@ module Devise
|
||||
# If the user is already confirmed, create an error for the user
|
||||
# Options must have the confirmation_token
|
||||
def confirm_by_token(confirmation_token)
|
||||
# When the `confirmation_token` parameter is blank, if there are any users with a blank
|
||||
# `confirmation_token` in the database, the first one would be confirmed here.
|
||||
# The error is being manually added here to ensure no users are confirmed by mistake.
|
||||
# This was done in the model for convenience, since validation errors are automatically
|
||||
# displayed in the view.
|
||||
if confirmation_token.blank?
|
||||
confirmable = new
|
||||
confirmable.errors.add(:confirmation_token, :blank)
|
||||
return confirmable
|
||||
end
|
||||
|
||||
confirmable = find_first_by_auth_conditions(confirmation_token: confirmation_token)
|
||||
|
||||
unless confirmable
|
||||
confirmation_digest = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
|
||||
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_digest)
|
||||
|
||||
@@ -80,16 +80,7 @@ module Devise
|
||||
# users to change relevant information like the e-mail without changing
|
||||
# their password). In case the password field is rejected, the confirmation
|
||||
# is also rejected as long as it is also blank.
|
||||
def update_with_password(params, *options)
|
||||
if options.present?
|
||||
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
|
||||
[Devise] The second argument of `DatabaseAuthenticatable#update_with_password`
|
||||
(`options`) is deprecated and it will be removed in the next major version.
|
||||
It was added to support a feature deprecated in Rails 4, so you can safely remove it
|
||||
from your code.
|
||||
DEPRECATION
|
||||
end
|
||||
|
||||
def update_with_password(params)
|
||||
current_password = params.delete(:current_password)
|
||||
|
||||
if params[:password].blank?
|
||||
@@ -98,9 +89,9 @@ module Devise
|
||||
end
|
||||
|
||||
result = if valid_password?(current_password)
|
||||
update(params, *options)
|
||||
update(params)
|
||||
else
|
||||
assign_attributes(params, *options)
|
||||
assign_attributes(params)
|
||||
valid?
|
||||
errors.add(:current_password, current_password.blank? ? :blank : :invalid)
|
||||
false
|
||||
@@ -122,20 +113,11 @@ module Devise
|
||||
# super(params)
|
||||
# end
|
||||
#
|
||||
def update_without_password(params, *options)
|
||||
if options.present?
|
||||
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
|
||||
[Devise] The second argument of `DatabaseAuthenticatable#update_without_password`
|
||||
(`options`) is deprecated and it will be removed in the next major version.
|
||||
It was added to support a feature deprecated in Rails 4, so you can safely remove it
|
||||
from your code.
|
||||
DEPRECATION
|
||||
end
|
||||
|
||||
def update_without_password(params)
|
||||
params.delete(:password)
|
||||
params.delete(:password_confirmation)
|
||||
|
||||
result = update(params, *options)
|
||||
result = update(params)
|
||||
clean_up_passwords
|
||||
result
|
||||
end
|
||||
|
||||
@@ -122,7 +122,15 @@ module Devise
|
||||
if Devise.paranoid
|
||||
super
|
||||
elsif access_locked? || (lock_strategy_enabled?(:failed_attempts) && attempts_exceeded?)
|
||||
:locked
|
||||
if unlock_strategy_enabled?(:both)
|
||||
'locked.both'.to_sym
|
||||
elsif unlock_strategy_enabled?(:email)
|
||||
'locked.email'.to_sym
|
||||
elsif unlock_strategy_enabled?(:time)
|
||||
'locked.time'.to_sym
|
||||
else
|
||||
'locked.none'.to_sym
|
||||
end
|
||||
elsif lock_strategy_enabled?(:failed_attempts) && last_attempt? && self.class.last_attempt_warning
|
||||
:last_attempt
|
||||
else
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'devise/hooks/trackable'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
# Track information about your user sign in. It tracks the following columns:
|
||||
@@ -36,6 +34,8 @@ module Devise
|
||||
# See https://github.com/plataformatec/devise/issues/4673 for more details.
|
||||
return if new_record?
|
||||
|
||||
return if skip_trackable_and_not_active_for_authentication?(request)
|
||||
|
||||
update_tracked_fields(request)
|
||||
save(validate: false)
|
||||
end
|
||||
@@ -46,6 +46,11 @@ module Devise
|
||||
request.remote_ip
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def skip_trackable_and_not_active_for_authentication?(request)
|
||||
request.env['devise.skip_trackable'] || !active_for_authentication?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ module Devise
|
||||
base.class_eval do
|
||||
validates_presence_of :email, if: :email_required?
|
||||
if Devise.activerecord51?
|
||||
validates_uniqueness_of :email, allow_blank: true, if: :will_save_change_to_email?
|
||||
validates_uniqueness_of :email, allow_blank: true, case_sensitive: true, if: :will_save_change_to_email?
|
||||
validates_format_of :email, with: email_regexp, allow_blank: true, if: :will_save_change_to_email?
|
||||
else
|
||||
validates_uniqueness_of :email, allow_blank: true, if: :email_changed?
|
||||
|
||||
@@ -130,8 +130,7 @@ module Devise
|
||||
#
|
||||
# Returns an +ActiveSupport::HashWithIndifferentAccess+.
|
||||
def cast_to_hash(params)
|
||||
# TODO: Remove the `with_indifferent_access` method call when we only support Rails 5+.
|
||||
params && params.to_h.with_indifferent_access
|
||||
params && params.to_h
|
||||
end
|
||||
|
||||
def default_params
|
||||
|
||||
@@ -135,10 +135,10 @@ module ActionDispatch::Routing
|
||||
# * failure_app: a rack app which is invoked whenever there is a failure. Strings representing a given
|
||||
# are also allowed as parameter.
|
||||
#
|
||||
# * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :get),
|
||||
# * sign_out_via: the HTTP method(s) accepted for the :sign_out action (default: :delete),
|
||||
# if you wish to restrict this to accept only :post or :delete requests you should do:
|
||||
#
|
||||
# devise_for :users, sign_out_via: [:post, :delete]
|
||||
# devise_for :users, sign_out_via: [:get, :post]
|
||||
#
|
||||
# You need to make sure that your sign_out controls trigger a request with a matching HTTP method.
|
||||
#
|
||||
|
||||
@@ -12,6 +12,7 @@ module Devise
|
||||
|
||||
if validate(resource){ hashed = true; resource.valid_password?(password) }
|
||||
remember_me(resource)
|
||||
resource.update_tracked_fields!(request) if resource.respond_to?(:update_tracked_fields!)
|
||||
resource.after_database_authentication
|
||||
success!(resource)
|
||||
end
|
||||
|
||||
@@ -139,7 +139,6 @@ module Devise
|
||||
|
||||
status, headers, response = Devise.warden_config[:failure_app].call(env).to_a
|
||||
@controller.response.headers.merge!(headers)
|
||||
@controller.response.content_type = headers["Content-Type"] unless Rails::VERSION::MAJOR >= 5
|
||||
@controller.status = status
|
||||
@controller.response.body = response.body
|
||||
nil # causes process return @response
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Devise
|
||||
VERSION = "4.6.2".freeze
|
||||
VERSION = "4.7.1".freeze
|
||||
end
|
||||
|
||||
@@ -82,23 +82,17 @@ RUBY
|
||||
postgresql?
|
||||
end
|
||||
|
||||
def rails5_and_up?
|
||||
Rails::VERSION::MAJOR >= 5
|
||||
end
|
||||
|
||||
def postgresql?
|
||||
config = ActiveRecord::Base.configurations[Rails.env]
|
||||
config && config['adapter'] == 'postgresql'
|
||||
end
|
||||
|
||||
def migration_version
|
||||
if rails5_and_up?
|
||||
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
||||
end
|
||||
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
||||
end
|
||||
|
||||
def primary_key_type
|
||||
primary_key_string if rails5_and_up?
|
||||
primary_key_string
|
||||
end
|
||||
|
||||
def primary_key_string
|
||||
|
||||
@@ -37,10 +37,6 @@ module Devise
|
||||
def show_readme
|
||||
readme "README" if behavior == :invoke
|
||||
end
|
||||
|
||||
def rails_4?
|
||||
Rails::VERSION::MAJOR == 4
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,7 +42,7 @@ module Devise
|
||||
def view_directory(name, _target_path = nil)
|
||||
directory name.to_s, _target_path || "#{target_path}/#{name}" do |content|
|
||||
if scope
|
||||
content.gsub "devise/shared/links", "#{plural_scope}/shared/links"
|
||||
content.gsub("devise/shared/links", "#{plural_scope}/shared/links").gsub("devise/shared/error_messages", "#{plural_scope}/shared/error_messages")
|
||||
else
|
||||
content
|
||||
end
|
||||
|
||||
4
lib/generators/templates/devise.rb
Executable file → Normal file
4
lib/generators/templates/devise.rb
Executable file → Normal file
@@ -103,7 +103,7 @@ Devise.setup do |config|
|
||||
# config.reload_routes = true
|
||||
|
||||
# ==> Configuration for :database_authenticatable
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 11. If
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 12. If
|
||||
# using other algorithms, it sets how many times you want the password to be hashed.
|
||||
#
|
||||
# Limiting the stretches to just one in testing will increase the performance of
|
||||
@@ -111,7 +111,7 @@ Devise.setup do |config|
|
||||
# a value less than 10 in other environments. Note that, for bcrypt (the default
|
||||
# algorithm), the cost increases exponentially with the number of stretches (e.g.
|
||||
# a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
|
||||
config.stretches = Rails.env.test? ? 1 : 11
|
||||
config.stretches = Rails.env.test? ? 1 : 12
|
||||
|
||||
# Set up a pepper to generate the hashed password.
|
||||
# config.pepper = '<%= SecureRandom.hex(64) %>'
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
autofocus: true,
|
||||
hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length),
|
||||
input_html: { autocomplete: "new-password" } %>
|
||||
<%= f.input :password_confirmation, label: "Confirm your new password", required: true %>
|
||||
<%= f.input :password_confirmation,
|
||||
label: "Confirm your new password",
|
||||
required: true,
|
||||
input_html: { autocomplete: "new-password" } %>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
|
||||
@@ -15,21 +15,21 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
|
||||
assert_equal @mock_warden, @controller.warden
|
||||
end
|
||||
|
||||
test 'proxy signed_in?(scope) to authenticate?' do
|
||||
@mock_warden.expects(:authenticate?).with(scope: :my_scope)
|
||||
test 'proxy signed_in?(scope) to authenticated?' do
|
||||
@mock_warden.expects(:authenticated?).with(scope: :my_scope)
|
||||
@controller.signed_in?(:my_scope)
|
||||
end
|
||||
|
||||
test 'proxy signed_in?(nil) to authenticate?' do
|
||||
test 'proxy signed_in?(nil) to authenticated?' do
|
||||
Devise.mappings.keys.each do |scope| # :user, :admin, :manager
|
||||
@mock_warden.expects(:authenticate?).with(scope: scope)
|
||||
@mock_warden.expects(:authenticated?).with(scope: scope)
|
||||
end
|
||||
@controller.signed_in?
|
||||
end
|
||||
|
||||
test 'proxy [group]_signed_in? to authenticate? with each scope' do
|
||||
test 'proxy [group]_signed_in? to authenticated? with each scope' do
|
||||
[:user, :admin].each do |scope|
|
||||
@mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
|
||||
@mock_warden.expects(:authenticated?).with(scope: scope).returns(false)
|
||||
end
|
||||
@controller.commenter_signed_in?
|
||||
end
|
||||
@@ -81,7 +81,7 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
|
||||
test 'proxy authenticate_[group]! to authenticate!? with each scope' do
|
||||
[:user, :admin].each do |scope|
|
||||
@mock_warden.expects(:authenticate!).with(scope: scope)
|
||||
@mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
|
||||
@mock_warden.expects(:authenticated?).with(scope: scope).returns(false)
|
||||
end
|
||||
@controller.authenticate_commenter!
|
||||
end
|
||||
@@ -91,18 +91,18 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
|
||||
@controller.authenticate_publisher_account!
|
||||
end
|
||||
|
||||
test 'proxy user_signed_in? to authenticate with user scope' do
|
||||
@mock_warden.expects(:authenticate).with(scope: :user).returns("user")
|
||||
test 'proxy user_signed_in? to authenticated? with user scope' do
|
||||
@mock_warden.expects(:authenticated?).with(scope: :user).returns("user")
|
||||
assert @controller.user_signed_in?
|
||||
end
|
||||
|
||||
test 'proxy admin_signed_in? to authenticatewith admin scope' do
|
||||
@mock_warden.expects(:authenticate).with(scope: :admin)
|
||||
test 'proxy admin_signed_in? to authenticated? with admin scope' do
|
||||
@mock_warden.expects(:authenticated?).with(scope: :admin)
|
||||
refute @controller.admin_signed_in?
|
||||
end
|
||||
|
||||
test 'proxy publisher_account_signed_in? to authenticate with namespaced publisher account scope' do
|
||||
@mock_warden.expects(:authenticate).with(scope: :publisher_account)
|
||||
test 'proxy publisher_account_signed_in? to authenticated? with namespaced publisher account scope' do
|
||||
@mock_warden.expects(:authenticated?).with(scope: :publisher_account)
|
||||
@controller.publisher_account_signed_in?
|
||||
end
|
||||
|
||||
|
||||
@@ -36,4 +36,10 @@ class PasswordsControllerTest < Devise::ControllerTestCase
|
||||
User.any_instance.expects :after_database_authentication
|
||||
put_update_with_params
|
||||
end
|
||||
|
||||
test 'redirects to new_password_path when token has expired' do
|
||||
@user.update(reset_password_sent_at: Time.now - 1.year)
|
||||
put_update_with_params
|
||||
assert_redirected_to new_user_password_path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -74,7 +74,7 @@ class SessionsControllerTest < Devise::ControllerTestCase
|
||||
assert_template "devise/sessions/new"
|
||||
end
|
||||
|
||||
test "#destroy doesn't set the flash if the requested format is not navigational" do
|
||||
test "#destroy doesn't set the flash and returns 204 status if the requested format is not navigational" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
user = create_user
|
||||
user.confirm
|
||||
@@ -88,6 +88,17 @@ class SessionsControllerTest < Devise::ControllerTestCase
|
||||
assert_equal 204, @response.status
|
||||
end
|
||||
|
||||
test "#destroy returns 401 status if user is not signed in and the requested format is not navigational" do
|
||||
delete :destroy, format: 'json'
|
||||
assert_equal 401, @response.status
|
||||
end
|
||||
|
||||
test "#destroy returns 302 status if user is not signed in and the requested format is navigational" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
delete :destroy
|
||||
assert_equal 302, @response.status
|
||||
end
|
||||
|
||||
if defined?(ActiveRecord) && ActiveRecord::Base.respond_to?(:mass_assignment_sanitizer)
|
||||
test "#new doesn't raise mass-assignment exception even if sign-in key is attr_protected" do
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
|
||||
5
test/devise_test.rb
Executable file → Normal file
5
test/devise_test.rb
Executable file → Normal file
@@ -90,11 +90,14 @@ class DeviseTest < ActiveSupport::TestCase
|
||||
[nil, ""].each do |empty|
|
||||
refute Devise.secure_compare(empty, "something")
|
||||
refute Devise.secure_compare("something", empty)
|
||||
refute Devise.secure_compare(empty, empty)
|
||||
end
|
||||
refute Devise.secure_compare("size_1", "size_four")
|
||||
end
|
||||
|
||||
test 'Devise.secure_compare should return true if strings are same' do
|
||||
assert Devise.secure_compare('', '')
|
||||
end
|
||||
|
||||
test 'Devise.email_regexp should match valid email addresses' do
|
||||
valid_emails = ["test@example.com", "jo@jo.co", "f4$_m@you.com", "testing.example@example.com.ua", "test@tt", "test@valid---domain.com"]
|
||||
non_valid_emails = ["rex", "test user@example.com", "test_user@example server.com"]
|
||||
|
||||
@@ -185,17 +185,27 @@ class FailureTest < ActiveSupport::TestCase
|
||||
|
||||
test 'uses the proxy failure message as symbol' do
|
||||
call_failure('warden' => OpenStruct.new(message: :invalid))
|
||||
assert_equal 'Invalid Email or password.', @request.flash[:alert]
|
||||
assert_equal 'Invalid email or password.', @request.flash[:alert]
|
||||
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
|
||||
end
|
||||
|
||||
test 'supports authentication_keys as a Hash for the flash message' do
|
||||
swap Devise, authentication_keys: { email: true, login: true } do
|
||||
call_failure('warden' => OpenStruct.new(message: :invalid))
|
||||
assert_equal 'Invalid Email, Login or password.', @request.flash[:alert]
|
||||
assert_equal 'Invalid email, login or password.', @request.flash[:alert]
|
||||
end
|
||||
end
|
||||
|
||||
test 'downcases authentication_keys for the flash message' do
|
||||
call_failure('warden' => OpenStruct.new(message: :invalid))
|
||||
assert_equal 'Invalid email or password.', @request.flash[:alert]
|
||||
end
|
||||
|
||||
test 'humanizes the flash message' do
|
||||
call_failure('warden' => OpenStruct.new(message: :invalid))
|
||||
assert_equal @request.flash[:alert], @request.flash[:alert].humanize
|
||||
end
|
||||
|
||||
test 'uses custom i18n options' do
|
||||
call_failure('warden' => OpenStruct.new(message: :does_not_exist), app: FailureWithI18nOptions)
|
||||
assert_equal 'User Steve does not exist', @request.flash[:alert]
|
||||
@@ -278,7 +288,7 @@ class FailureTest < ActiveSupport::TestCase
|
||||
|
||||
test 'uses the failure message as response body' do
|
||||
call_failure('formats' => Mime[:xml], 'warden' => OpenStruct.new(message: :invalid))
|
||||
assert_match '<error>Invalid Email or password.</error>', @response.third.body
|
||||
assert_match '<error>Invalid email or password.</error>', @response.third.body
|
||||
end
|
||||
|
||||
context 'on ajax call' do
|
||||
@@ -327,7 +337,7 @@ class FailureTest < ActiveSupport::TestCase
|
||||
}
|
||||
call_failure(env)
|
||||
assert @response.third.body.include?('<h2>Log in</h2>')
|
||||
assert @response.third.body.include?('Invalid Email or password.')
|
||||
assert @response.third.body.include?('Invalid email or password.')
|
||||
end
|
||||
|
||||
test 'calls the original controller if not confirmed email' do
|
||||
@@ -362,7 +372,7 @@ class FailureTest < ActiveSupport::TestCase
|
||||
}
|
||||
call_failure(env)
|
||||
assert @response.third.body.include?('<h2>Log in</h2>')
|
||||
assert @response.third.body.include?('Invalid Email or password.')
|
||||
assert @response.third.body.include?('Invalid email or password.')
|
||||
assert_equal @request.env["SCRIPT_NAME"], '/sample'
|
||||
assert_equal @request.env["PATH_INFO"], '/users/sign_in'
|
||||
end
|
||||
|
||||
@@ -48,7 +48,6 @@ if DEVISE_ORM == :active_record
|
||||
run_generator %w(monster)
|
||||
assert_file "app/models/monster.rb"
|
||||
run_generator %w(monster)
|
||||
|
||||
if Rails.version >= '5.0.3'
|
||||
assert_migration "db2/migrate/add_devise_to_monsters.rb"
|
||||
else
|
||||
@@ -84,11 +83,7 @@ if DEVISE_ORM == :active_record
|
||||
|
||||
test "add primary key type with rails 5 when specified in rails generator" do
|
||||
run_generator ["monster", "--primary_key_type=uuid"]
|
||||
if Devise::Test.rails5_and_up?
|
||||
assert_migration "db/migrate/devise_create_monsters.rb", /create_table :monsters, id: :uuid do/
|
||||
else
|
||||
assert_migration "db/migrate/devise_create_monsters.rb", /create_table :monsters do/
|
||||
end
|
||||
assert_migration "db/migrate/devise_create_monsters.rb", /create_table :monsters, id: :uuid do/
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -11,16 +11,19 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
|
||||
run_generator
|
||||
assert_files
|
||||
assert_shared_links
|
||||
assert_error_messages
|
||||
end
|
||||
|
||||
test "Assert all views are properly created with scope param" do
|
||||
run_generator %w(users)
|
||||
assert_files "users"
|
||||
assert_shared_links "users"
|
||||
assert_error_messages "users"
|
||||
|
||||
run_generator %w(admins)
|
||||
assert_files "admins"
|
||||
assert_shared_links "admins"
|
||||
assert_error_messages "admins"
|
||||
end
|
||||
|
||||
test "Assert views with simple form" do
|
||||
@@ -88,6 +91,7 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
|
||||
assert_file "app/views/#{scope}/registrations/edit.html.erb"
|
||||
assert_file "app/views/#{scope}/sessions/new.html.erb"
|
||||
assert_file "app/views/#{scope}/shared/_links.html.erb"
|
||||
assert_file "app/views/#{scope}/shared/_error_messages.html.erb"
|
||||
assert_file "app/views/#{scope}/unlocks/new.html.erb"
|
||||
end
|
||||
|
||||
@@ -102,4 +106,16 @@ class ViewsGeneratorTest < Rails::Generators::TestCase
|
||||
assert_file "app/views/#{scope}/sessions/new.html.erb", link
|
||||
assert_file "app/views/#{scope}/unlocks/new.html.erb", link
|
||||
end
|
||||
|
||||
def assert_error_messages(scope = nil)
|
||||
scope = "devise" if scope.nil?
|
||||
link = /<%= render \"#{scope}\/shared\/error_messages\", resource: resource %>/
|
||||
|
||||
assert_file "app/views/#{scope}/passwords/edit.html.erb", link
|
||||
assert_file "app/views/#{scope}/passwords/new.html.erb", link
|
||||
assert_file "app/views/#{scope}/confirmations/new.html.erb", link
|
||||
assert_file "app/views/#{scope}/registrations/new.html.erb", link
|
||||
assert_file "app/views/#{scope}/registrations/edit.html.erb", link
|
||||
assert_file "app/views/#{scope}/unlocks/new.html.erb", link
|
||||
end
|
||||
end
|
||||
|
||||
@@ -557,7 +557,7 @@ class AuthenticationKeysTest < Devise::IntegrationTest
|
||||
test 'missing authentication keys cause authentication to abort' do
|
||||
swap Devise, authentication_keys: [:subdomain] do
|
||||
sign_in_as_user
|
||||
assert_contain "Invalid Subdomain or password."
|
||||
assert_contain "Invalid subdomain or password."
|
||||
refute warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
@@ -596,7 +596,7 @@ class AuthenticationRequestKeysTest < Devise::IntegrationTest
|
||||
|
||||
swap Devise, request_keys: [:subdomain] do
|
||||
sign_in_as_user
|
||||
assert_contain "Invalid Email or password."
|
||||
assert_contain "Invalid email or password."
|
||||
refute warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -142,7 +142,7 @@ class ConfirmationTest < Devise::IntegrationTest
|
||||
fill_in 'password', with: 'invalid'
|
||||
end
|
||||
|
||||
assert_contain 'Invalid Email or password'
|
||||
assert_contain 'Invalid email or password'
|
||||
refute warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
@@ -175,6 +175,36 @@ class ConfirmationTest < Devise::IntegrationTest
|
||||
assert_current_url '/users/sign_in'
|
||||
end
|
||||
|
||||
test "should not be able to confirm an email with a blank confirmation token" do
|
||||
visit_user_confirmation_with_token("")
|
||||
|
||||
assert_contain "Confirmation token can't be blank"
|
||||
end
|
||||
|
||||
test "should not be able to confirm an email with a nil confirmation token" do
|
||||
visit_user_confirmation_with_token(nil)
|
||||
|
||||
assert_contain "Confirmation token can't be blank"
|
||||
end
|
||||
|
||||
test "should not be able to confirm user with blank confirmation token" do
|
||||
user = create_user(confirm: false)
|
||||
user.update_attribute(:confirmation_token, "")
|
||||
|
||||
visit_user_confirmation_with_token("")
|
||||
|
||||
assert_contain "Confirmation token can't be blank"
|
||||
end
|
||||
|
||||
test "should not be able to confirm user with nil confirmation token" do
|
||||
user = create_user(confirm: false)
|
||||
user.update_attribute(:confirmation_token, nil)
|
||||
|
||||
visit_user_confirmation_with_token(nil)
|
||||
|
||||
assert_contain "Confirmation token can't be blank"
|
||||
end
|
||||
|
||||
test 'error message is configurable by resource name' do
|
||||
store_translations :en, devise: {
|
||||
failure: { user: { unconfirmed: "Not confirmed user" } }
|
||||
|
||||
@@ -70,7 +70,7 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest
|
||||
fill_in 'password', with: 'abcdef'
|
||||
end
|
||||
|
||||
assert_contain 'Invalid Email or password'
|
||||
assert_contain 'Invalid email or password'
|
||||
refute warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
@@ -82,7 +82,7 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest
|
||||
end
|
||||
|
||||
assert_not_contain 'Not found in database'
|
||||
assert_contain 'Invalid Email or password.'
|
||||
assert_contain 'Invalid email or password.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -52,7 +52,7 @@ class HttpAuthenticationTest < Devise::IntegrationTest
|
||||
sign_in_as_new_user_with_http("unknown")
|
||||
assert_equal 401, status
|
||||
assert_equal "application/xml; charset=utf-8", headers["Content-Type"]
|
||||
assert_match "<error>Invalid Email or password.</error>", response.body
|
||||
assert_match "<error>Invalid email or password.</error>", response.body
|
||||
end
|
||||
|
||||
test 'returns a custom response with www-authenticate and chosen realm' do
|
||||
|
||||
@@ -104,7 +104,7 @@ class LockTest < Devise::IntegrationTest
|
||||
|
||||
test 'error message is configurable by resource name' do
|
||||
store_translations :en, devise: {
|
||||
failure: {user: {locked: "You are locked!"}}
|
||||
failure: {user: {locked: { both: "You are locked!" }}}
|
||||
} do
|
||||
|
||||
user = create_user(locked: true)
|
||||
@@ -118,7 +118,7 @@ class LockTest < Devise::IntegrationTest
|
||||
|
||||
test "user should not be able to sign in when locked" do
|
||||
store_translations :en, devise: {
|
||||
failure: {user: {locked: "You are locked!"}}
|
||||
failure: {user: {locked: {both: "You are locked!"}}}
|
||||
} do
|
||||
|
||||
user = create_user(locked: true)
|
||||
|
||||
@@ -152,6 +152,19 @@ class PasswordTest < Devise::IntegrationTest
|
||||
refute user.reload.valid_password?('987654321')
|
||||
end
|
||||
|
||||
test 'not authenticated user with expired reset password token should be redirected to new password path' do
|
||||
user = create_user
|
||||
request_forgot_password
|
||||
user.update(reset_password_sent_at: Time.now - 1.year)
|
||||
|
||||
visit edit_user_password_path(reset_password_token: 'abcdef')
|
||||
fill_in 'New password', with: '987654321'
|
||||
fill_in 'Confirm new password', with: '987654321'
|
||||
click_button 'Change my password'
|
||||
|
||||
assert_contain 'The password recovery link expired. Please request a new one.'
|
||||
end
|
||||
|
||||
test 'not authenticated user with valid reset password token but invalid password should not be able to change their password' do
|
||||
user = create_user
|
||||
request_forgot_password
|
||||
|
||||
@@ -14,10 +14,8 @@ class RememberMeTest < Devise::IntegrationTest
|
||||
def generate_signed_cookie(raw_cookie)
|
||||
request = if Devise::Test.rails51? || Devise::Test.rails52_and_up?
|
||||
ActionController::TestRequest.create(Class.new) # needs a "controller class"
|
||||
elsif Devise::Test.rails5?
|
||||
ActionController::TestRequest.create
|
||||
else
|
||||
ActionController::TestRequest.new
|
||||
ActionController::TestRequest.create
|
||||
end
|
||||
request.cookie_jar.signed['raw_cookie'] = raw_cookie
|
||||
request.cookie_jar['raw_cookie']
|
||||
|
||||
@@ -95,5 +95,4 @@ class TrackableHooksTest < Devise::IntegrationTest
|
||||
user.reload
|
||||
assert_equal 1, user.sign_in_count
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -77,6 +77,24 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
|
||||
end
|
||||
|
||||
test 'should return a new record with errors when a blank token is given and a record exists on the database' do
|
||||
user = create_user(confirmation_token: '')
|
||||
|
||||
confirmed_user = User.confirm_by_token('')
|
||||
|
||||
refute user.reload.confirmed?
|
||||
assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
|
||||
end
|
||||
|
||||
test 'should return a new record with errors when a nil token is given and a record exists on the database' do
|
||||
user = create_user(confirmation_token: nil)
|
||||
|
||||
confirmed_user = User.confirm_by_token(nil)
|
||||
|
||||
refute user.reload.confirmed?
|
||||
assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
|
||||
end
|
||||
|
||||
test 'should generate errors for a user email if user is already confirmed' do
|
||||
user = create_user
|
||||
user.confirmed_at = Time.now
|
||||
|
||||
@@ -312,7 +312,7 @@ class LockableTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'should return last attempt message if user made next-to-last attempt of password entering' do
|
||||
swap Devise, last_attempt_warning: true, lock_strategy: :failed_attempts do
|
||||
swap Devise, last_attempt_warning: true, lock_strategy: :failed_attempts, unlock_strategy: :none do
|
||||
user = create_user
|
||||
user.failed_attempts = Devise.maximum_attempts - 2
|
||||
assert_equal :invalid, user.unauthenticated_message
|
||||
@@ -321,7 +321,7 @@ class LockableTest < ActiveSupport::TestCase
|
||||
assert_equal :last_attempt, user.unauthenticated_message
|
||||
|
||||
user.failed_attempts = Devise.maximum_attempts
|
||||
assert_equal :locked, user.unauthenticated_message
|
||||
assert_equal :'locked.none', user.unauthenticated_message
|
||||
end
|
||||
end
|
||||
|
||||
@@ -336,7 +336,22 @@ class LockableTest < ActiveSupport::TestCase
|
||||
test 'should return locked message if user was programatically locked' do
|
||||
user = create_user
|
||||
user.lock_access!
|
||||
assert_equal :locked, user.unauthenticated_message
|
||||
|
||||
swap Devise, unlock_strategy: :none do
|
||||
assert_equal :'locked.none', user.unauthenticated_message
|
||||
end
|
||||
|
||||
swap Devise, unlock_strategy: :both do
|
||||
assert_equal :'locked.both', user.unauthenticated_message
|
||||
end
|
||||
|
||||
swap Devise, unlock_strategy: :email do
|
||||
assert_equal :'locked.email', user.unauthenticated_message
|
||||
end
|
||||
|
||||
swap Devise, unlock_strategy: :time do
|
||||
assert_equal :'locked.time', user.unauthenticated_message
|
||||
end
|
||||
end
|
||||
|
||||
test 'unlock_strategy_enabled? should return true for both, email, and time strategies if :both is used' do
|
||||
|
||||
@@ -60,6 +60,39 @@ class TrackableTest < ActiveSupport::TestCase
|
||||
assert_not user.update_tracked_fields!(request)
|
||||
end
|
||||
|
||||
test "update_tracked_fields! runs when isn't a new record and the validations are ok" do
|
||||
user = create_user
|
||||
user.stubs(:active_for_authentication?).returns(true)
|
||||
|
||||
request = mock
|
||||
request.stubs(:remote_ip).returns("127.0.0.1")
|
||||
request.stubs(:env).returns('devise.skip_trackable' => nil)
|
||||
|
||||
assert user.update_tracked_fields!(request)
|
||||
end
|
||||
|
||||
test "update_tracked_fields! should not run when skip trackable is turned on" do
|
||||
user = create_user
|
||||
user.stubs(:active_for_authentication?).returns(true)
|
||||
|
||||
request = mock
|
||||
request.stubs(:remote_ip).returns("127.0.0.1")
|
||||
request.stubs(:env).returns('devise.skip_trackable' => 1)
|
||||
|
||||
assert_not user.update_tracked_fields!(request)
|
||||
end
|
||||
|
||||
test "update_tracked_fields! should not run when the user is not active for authentication" do
|
||||
user = create_user
|
||||
user.stubs(:active_for_authentication?).returns(false)
|
||||
|
||||
request = mock
|
||||
request.stubs(:remote_ip).returns("127.0.0.1")
|
||||
request.stubs(:env).returns('devise.skip_trackable' => nil)
|
||||
|
||||
assert_not user.update_tracked_fields!(request)
|
||||
end
|
||||
|
||||
test 'extract_ip_from should be overridable' do
|
||||
class UserWithOverride < User
|
||||
protected
|
||||
|
||||
@@ -5,20 +5,16 @@ ActiveRecord::Base.logger = Logger.new(nil)
|
||||
ActiveRecord::Base.include_root_in_json = true
|
||||
|
||||
migrate_path = File.expand_path("../../rails_app/db/migrate/", __FILE__)
|
||||
if Devise::Test.rails52_and_up?
|
||||
if Devise::Test.rails6?
|
||||
ActiveRecord::MigrationContext.new(migrate_path, ActiveRecord::SchemaMigration).migrate
|
||||
elsif Devise::Test.rails52_and_up?
|
||||
ActiveRecord::MigrationContext.new(migrate_path).migrate
|
||||
else
|
||||
ActiveRecord::Migrator.migrate(migrate_path)
|
||||
end
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
if Devise::Test.rails5_and_up?
|
||||
self.use_transactional_tests = true
|
||||
else
|
||||
# Let `after_commit` work with transactional fixtures, however this is not needed for Rails 5.
|
||||
require 'test_after_commit'
|
||||
self.use_transactional_fixtures = true
|
||||
end
|
||||
self.use_transactional_tests = true
|
||||
|
||||
self.use_instantiated_fixtures = false
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ require 'shared_user'
|
||||
class User < ActiveRecord::Base
|
||||
include Shim
|
||||
include SharedUser
|
||||
include ActiveModel::Serializers::Xml if Devise::Test.rails5_and_up?
|
||||
include ActiveModel::Serializers::Xml
|
||||
|
||||
validates :sign_in_count, presence: true
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@ class HomeController < ApplicationController
|
||||
end
|
||||
|
||||
def unauthenticated
|
||||
if Devise::Test.rails5_and_up?
|
||||
render body: "unauthenticated", status: :unauthorized
|
||||
else
|
||||
render text: "unauthenticated", status: :unauthorized
|
||||
end
|
||||
render body: "unauthenticated", status: :unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,6 +11,6 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
user = User.to_adapter.find_first(email: 'user@test.com')
|
||||
user.remember_me = true
|
||||
sign_in user
|
||||
render (Devise::Test.rails5_and_up? ? :body : :text) => ""
|
||||
render body: ""
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def update_form
|
||||
render (Devise::Test.rails5_and_up? ? :body : :text) => 'Update'
|
||||
render body: 'Update'
|
||||
end
|
||||
|
||||
def accept
|
||||
@@ -23,11 +23,11 @@ class UsersController < ApplicationController
|
||||
end
|
||||
|
||||
def exhibit
|
||||
render (Devise::Test.rails5_and_up? ? :body : :text) => current_user ? "User is authenticated" : "User is not authenticated"
|
||||
render body: current_user ? "User is authenticated" : "User is not authenticated"
|
||||
end
|
||||
|
||||
def expire
|
||||
user_session['last_request_at'] = 31.minutes.ago.utc
|
||||
render (Devise::Test.rails5_and_up? ? :body : :text) => 'User will be expired on next request'
|
||||
render body: 'User will be expired on next request'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Welcome to "sessions/new" view!
|
||||
<%= render file: "devise/sessions/new" %>
|
||||
<%= render template: "devise/sessions/new" %>
|
||||
|
||||
@@ -33,20 +33,14 @@ module RailsApp
|
||||
# config.assets.enabled = false
|
||||
|
||||
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
|
||||
rails_version = Gem::Version.new(Rails.version)
|
||||
if DEVISE_ORM == :active_record &&
|
||||
rails_version >= Gem::Version.new('4.2.0') &&
|
||||
rails_version < Gem::Version.new('5.1.0')
|
||||
config.active_record.raise_in_transactional_callbacks = true
|
||||
end
|
||||
|
||||
# This was used to break devise in some situations
|
||||
config.to_prepare do
|
||||
Devise::SessionsController.layout "application"
|
||||
end
|
||||
|
||||
# Remove this check once Rails 5.0 support is removed.
|
||||
if Devise::Test.rails52_and_up?
|
||||
# Remove the first check once Rails 5.0 support is removed.
|
||||
if Devise::Test.rails52_and_up? && !Devise::Test.rails6?
|
||||
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,8 +6,11 @@ end
|
||||
|
||||
module Devise
|
||||
module Test
|
||||
# Detection for minor differences between Rails 4 and 5, 5.1, and 5.2 in tests.
|
||||
|
||||
# Detection for minor differences between Rails versions in tests.
|
||||
def self.rails6?
|
||||
Rails.version.start_with? '6'
|
||||
end
|
||||
|
||||
def self.rails52_and_up?
|
||||
Rails::VERSION::MAJOR > 5 || rails52?
|
||||
end
|
||||
@@ -19,14 +22,6 @@ module Devise
|
||||
def self.rails51?
|
||||
Rails.version.start_with? '5.1'
|
||||
end
|
||||
|
||||
def self.rails5_and_up?
|
||||
Rails::VERSION::MAJOR >= 5
|
||||
end
|
||||
|
||||
def self.rails5?
|
||||
Rails.version.start_with? '5'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -22,13 +22,7 @@ RailsApp::Application.configure do
|
||||
# config.action_dispatch.rack_cache = true
|
||||
|
||||
# Disable Rails's static asset server (Apache or nginx will already do this).
|
||||
if Devise::Test.rails5_and_up?
|
||||
config.public_file_server.enabled = false
|
||||
elsif Rails.version >= "4.2.0"
|
||||
config.serve_static_files = false
|
||||
else
|
||||
config.serve_static_assets = false
|
||||
end
|
||||
config.public_file_server.enabled = false
|
||||
|
||||
# Compress JavaScripts and CSS.
|
||||
config.assets.js_compressor = :uglifier
|
||||
|
||||
@@ -16,16 +16,8 @@ RailsApp::Application.configure do
|
||||
|
||||
# Disable serving static files from the `/public` folder by default since
|
||||
# Apache or NGINX already handles this.
|
||||
if Devise::Test.rails5_and_up?
|
||||
config.public_file_server.enabled = true
|
||||
config.public_file_server.headers = {'Cache-Control' => 'public, max-age=3600'}
|
||||
elsif Rails.version >= "4.2.0"
|
||||
config.serve_static_files = true
|
||||
config.static_cache_control = "public, max-age=3600"
|
||||
else
|
||||
config.serve_static_assets = true
|
||||
config.static_cache_control = "public, max-age=3600"
|
||||
end
|
||||
config.public_file_server.enabled = true
|
||||
config.public_file_server.headers = {'Cache-Control' => 'public, max-age=3600'}
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
superclass = ActiveRecord::Migration
|
||||
# TODO: Inherit from the 5.0 Migration class directly when we drop support for Rails 4.
|
||||
superclass = ActiveRecord::Migration[5.0] if superclass.respond_to?(:[])
|
||||
|
||||
class CreateTables < superclass
|
||||
class CreateTables < ActiveRecord::Migration[5.0]
|
||||
def self.up
|
||||
create_table :users do |t|
|
||||
t.string :username
|
||||
|
||||
@@ -204,8 +204,7 @@ class CustomizedRoutingTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test 'map with format false for sessions' do
|
||||
expected_params = {controller: 'devise/sessions', action: 'new'}
|
||||
expected_params[:format] = false if Devise::Test.rails5_and_up?
|
||||
expected_params = {controller: 'devise/sessions', action: 'new', format: false}
|
||||
|
||||
assert_recognizes(expected_params, {path: '/htmlonly_admin/sign_in', method: :get})
|
||||
assert_raise ExpectedRoutingError do
|
||||
@@ -214,8 +213,7 @@ class CustomizedRoutingTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test 'map with format false for passwords' do
|
||||
expected_params = {controller: 'devise/passwords', action: 'create'}
|
||||
expected_params[:format] = false if Devise::Test.rails5_and_up?
|
||||
expected_params = {controller: 'devise/passwords', action: 'create', format: false}
|
||||
|
||||
assert_recognizes(expected_params, {path: '/htmlonly_admin/password', method: :post})
|
||||
assert_raise ExpectedRoutingError do
|
||||
@@ -224,8 +222,7 @@ class CustomizedRoutingTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test 'map with format false for registrations' do
|
||||
expected_params = {controller: 'devise/registrations', action: 'new'}
|
||||
expected_params[:format] = false if Devise::Test.rails5_and_up?
|
||||
expected_params = {controller: 'devise/registrations', action: 'new', format: false}
|
||||
|
||||
assert_recognizes(expected_params, {path: '/htmlonly_admin/sign_up', method: :get})
|
||||
assert_raise ExpectedRoutingError do
|
||||
@@ -234,8 +231,7 @@ class CustomizedRoutingTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test 'map with format false for confirmations' do
|
||||
expected_params = {controller: 'devise/confirmations', action: 'show'}
|
||||
expected_params[:format] = false if Devise::Test.rails5_and_up?
|
||||
expected_params = {controller: 'devise/confirmations', action: 'show', format: false}
|
||||
|
||||
assert_recognizes(expected_params, {path: '/htmlonly_users/confirmation', method: :get})
|
||||
assert_raise ExpectedRoutingError do
|
||||
@@ -244,8 +240,7 @@ class CustomizedRoutingTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
test 'map with format false for unlocks' do
|
||||
expected_params = {controller: 'devise/unlocks', action: 'show'}
|
||||
expected_params[:format] = false if Devise::Test.rails5_and_up?
|
||||
expected_params = {controller: 'devise/unlocks', action: 'show', format: false}
|
||||
|
||||
assert_recognizes(expected_params, {path: '/htmlonly_users/unlock', method: :get})
|
||||
assert_raise ExpectedRoutingError do
|
||||
|
||||
@@ -44,38 +44,12 @@ class Rails52SecretKeyBase
|
||||
def config
|
||||
OpenStruct.new(secret_key_base: nil)
|
||||
end
|
||||
|
||||
|
||||
def secret_key_base
|
||||
'secret_key_base'
|
||||
end
|
||||
end
|
||||
|
||||
class Rails41Secrets
|
||||
def secrets
|
||||
OpenStruct.new(secret_key_base: 'secrets')
|
||||
end
|
||||
|
||||
def config
|
||||
OpenStruct.new(secret_key_base: nil)
|
||||
end
|
||||
end
|
||||
|
||||
class Rails41Config
|
||||
def secrets
|
||||
OpenStruct.new(secret_key_base: nil)
|
||||
end
|
||||
|
||||
def config
|
||||
OpenStruct.new(secret_key_base: 'config')
|
||||
end
|
||||
end
|
||||
|
||||
class Rails40Config
|
||||
def config
|
||||
OpenStruct.new(secret_key_base: 'config')
|
||||
end
|
||||
end
|
||||
|
||||
class SecretKeyFinderTest < ActiveSupport::TestCase
|
||||
test "rails 5.2 uses credentials when they're available" do
|
||||
secret_key_finder = Devise::SecretKeyFinder.new(Rails52Credentials.new)
|
||||
@@ -100,22 +74,4 @@ class SecretKeyFinderTest < ActiveSupport::TestCase
|
||||
|
||||
assert_equal 'secret_key_base', secret_key_finder.find
|
||||
end
|
||||
|
||||
test "rails 4.1 uses secrets" do
|
||||
secret_key_finder = Devise::SecretKeyFinder.new(Rails41Secrets.new)
|
||||
|
||||
assert_equal 'secrets', secret_key_finder.find
|
||||
end
|
||||
|
||||
test "rails 4.1 uses config when secrets are empty" do
|
||||
secret_key_finder = Devise::SecretKeyFinder.new(Rails41Config.new)
|
||||
|
||||
assert_equal 'config', secret_key_finder.find
|
||||
end
|
||||
|
||||
test "rails 4.0 uses config" do
|
||||
secret_key_finder = Devise::SecretKeyFinder.new(Rails40Config.new)
|
||||
|
||||
assert_equal 'config', secret_key_finder.find
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,21 +6,11 @@ module Devise
|
||||
# xhr get_via_redirect post_via_redirect
|
||||
# ).each do |method|
|
||||
%w( get post put ).each do |method|
|
||||
if Devise::Test.rails5_and_up?
|
||||
define_method(method) do |url, options={}|
|
||||
if options.empty?
|
||||
super url
|
||||
else
|
||||
super url, options
|
||||
end
|
||||
end
|
||||
else
|
||||
define_method(method) do |url, options={}|
|
||||
if options[:xhr]==true
|
||||
xml_http_request __method__, url, options[:params] || {}, options[:headers]
|
||||
else
|
||||
super url, options[:params] || {}, options[:headers]
|
||||
end
|
||||
define_method(method) do |url, options={}|
|
||||
if options.empty?
|
||||
super url
|
||||
else
|
||||
super url, options
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -31,21 +21,11 @@ module Devise
|
||||
# xhr get_via_redirect post_via_redirect
|
||||
# ).each do |method|
|
||||
%w( get post put ).each do |method|
|
||||
if Devise::Test.rails5_and_up?
|
||||
define_method(method) do |action, options={}|
|
||||
if options.empty?
|
||||
super action
|
||||
else
|
||||
super action, options
|
||||
end
|
||||
end
|
||||
else
|
||||
define_method(method) do |action, options={}|
|
||||
if options[:xhr]==true
|
||||
xml_http_request __method__, action, options[:params] || {}, options[:headers]
|
||||
else
|
||||
super action, options[:params] || {}, options[:headers]
|
||||
end
|
||||
define_method(method) do |action, options={}|
|
||||
if options.empty?
|
||||
super action
|
||||
else
|
||||
super action, options
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -102,7 +102,12 @@ class TestControllerHelpersTest < Devise::ControllerTestCase
|
||||
|
||||
test "returns the content type of a failure app" do
|
||||
get :index, params: { format: :xml }
|
||||
assert response.content_type.include?('application/xml')
|
||||
|
||||
if Devise::Test.rails6?
|
||||
assert response.media_type.include?('application/xml')
|
||||
else
|
||||
assert response.content_type.include?('application/xml')
|
||||
end
|
||||
end
|
||||
|
||||
test "defined Warden after_authentication callback should not be called when sign_in is called" do
|
||||
@@ -173,10 +178,8 @@ class TestControllerHelpersTest < Devise::ControllerTestCase
|
||||
|
||||
@request = if Devise::Test.rails51? || Devise::Test.rails52_and_up?
|
||||
ActionController::TestRequest.create(Class.new) # needs a "controller class"
|
||||
elsif Devise::Test.rails5?
|
||||
ActionController::TestRequest.create
|
||||
else
|
||||
ActionController::TestRequest.new
|
||||
ActionController::TestRequest.create
|
||||
end
|
||||
|
||||
new_warden_proxy = warden
|
||||
|
||||
Reference in New Issue
Block a user