* `changed?` behaviour has been updated
Due to 16ae3db5a5 `changed?` has been updated to check for dirtiness after save. The new method that behaves like the old `changed` is `saved_changes?`.
* Add comment to explain which method to used based on which rails version it is
As reported in https://github.com/plataformatec/devise/issues/5071, if
for some reason, a user in the database had the `confirmation_token`
column as a blank string, Devise would confirm that user after receiving
a request with a blank `confirmation_token` parameter.
After this commit, a request sending a blank `confirmation_token`
parameter will receive a validation error.
For applications that have users with a blank `confirmation_token` in
the database, it's recommended to manually regenerate or to nullify
them.
Comment incorrectly states that default method is "get", while line 228 of /lib/devise.rb sets "delete": "The default method used while signing out: @@sign_out_via = :delete"
As reported in #4981, the method `#increment_failed_attempts` of `Devise::Models::Lockable` was
not concurrency safe. The increment operation was being done in two steps: first the value was read from the database, and then incremented by 1. This may result in wrong values if two requests try to update the value concurrently. For example:
```
Browser1 -------> Read `failed_attempts` from DB (1) -------> Increment `failed_attempts` to 2
Browser2 -------> Read `failed_attempts` from DB (1) -------> Increment `failed_attempts` to 2
```
In the example above, `failed_attempts` should have been set to 3, but it will be set to 2.
This commit handles this case by calling `ActiveRecord::CounterCache.increment_counter` method, which will do both steps at once, reading the value straight from the database.
This commit also adds a `ActiveRecord::AttributeMethods::Dirty#reload` call to ensure that the application gets the updated value - i.e. that other request might have updated.
Although this does not ensure that the value is in fact the most recent one - other request could've updated it after the `reload` call - it seems good enough for this implementation.
Even if a request does not locks the account because it has a stale value, the next one - that updated that value - will do it. That's why we decided not to use a pessimistic lock here.
Closes#4981.
If `Confirmable#confirmation_sent_at` is equal to `0.days.ago`, then
`confirmation_period_valid?` will be deemed valid even if the setting is
configured to disable this outright. To prevent this error, we explicitly
check the configuration setting to be `0.days.ago`.
If called with a hash that has a `default` / `default_proc`
configured, `Devise::ParameterFilter` can add in missing keys
it was due to attempt to sanitise the values for.
This patch prevents this from happening, whilst also clarifying
the filtering intent of `ParamaterFilter`.
(This can also occur if NilClass has been augmented with definitions
for `strip` or `downcase`.)
Fixes#3431.