Compare commits

...

79 Commits

Author SHA1 Message Date
Carlos Antonio da Silva
d5a48b49dc Release v4.9.4 2024-04-10 09:27:12 -03:00
Carlos Antonio da Silva
bab47e1c1f Adds Ruby 3.3 to CI on 4-stable
Related: #5668
2024-04-09 17:12:52 -03:00
Carlos Antonio da Silva
cee7457d7f Bump year [ci skip] 2024-04-09 16:58:42 -03:00
Carlos Antonio da Silva
95ed7d3dd8 Merge pull request #5641 from henryaj/patch-1
Fix README anchor link [ci skip]
2023-10-13 11:57:29 -03:00
Carlos Antonio da Silva
edffc79bf0 Respect locale set by controller in the failure app (#5567)
A common usage of I18n with different locales is to create some around
callback in the application controller that sets the locale for the
entire action, via params/url/user/etc., which ensure the locale is
respected for the duration of that action, and resets at the end.

Devise was not respecting the locale when the authenticate failed and
triggered the failure app, because that happens in a warden middleware
right up in the change, by that time the controller around callback had
already reset the locale back to its default, and the failure app would
just translate flash messages using the default locale.

Now we are passing the current locale down to the failure app via warden
options, and wrapping it with an around callback, which makes the
failure app respect the set I18n locale by the controller at the time
the authentication failure is triggered, working as expected. (much more
like a normal controller would.)

I chose to introduce a callback in the failure app so we could wrap the
whole `respond` action processing rather than adding individual `locale`
options to the `I18n.t` calls, because that should ensure other possible
`I18n.t` calls from overridden failure apps would respect the set locale
as well, and makes it more like one would implement in a controller. I
don't recommend people using callbacks in their own failure apps though,
as this is not going to be documented as a "feature" of failures apps,
it's considered "internal" and could be refactored at any point.

It is possible to override the locale with the new `i18n_locale` method,
which simply defaults to the passed locale from the controller.

Closes #5247
Closes #5246

Related to: #3052, #4823, and possible others already closed.
Related to warden: (may be closed there afterwards)
https://github.com/wardencommunity/warden/issues/180
https://github.com/wardencommunity/warden/issues/170
2023-10-13 11:19:45 -03:00
Carlos Antonio da Silva
1d6658097e Release v4.9.3 2023-10-11 19:08:36 -03:00
Carlos Antonio da Silva
dcbfb32e66 Merge pull request #5640 from nmaggioni/nm_config_template_typo
Fix typo in config template
2023-10-11 11:41:16 -03:00
Carlos Antonio da Silva
c146b25f31 Better clarify need to override internal_methods
Co-authored-by: Eebs Kobeissi <ebrahim.kobeissi@gmail.com>
2023-10-10 19:51:06 -03:00
Carlos Antonio da Silva
9a08620378 Update changelog with Rails 7.1 mention [ci skip] 2023-10-10 19:51:04 -03:00
Carlos Antonio da Silva
407f223c65 Fix test warning about deprecated cache format in Rails 7.1 2023-10-10 11:39:30 -03:00
Carlos Antonio da Silva
f2a42abbf4 Ensure _prefixes is not available as an action method on controllers
There was a change introduced in Rails 7.1 that causes all public
actions of non-abstract controllers to become action methods, even if
they happen to match the name of an internal method defined by abstract
`ActionController::Base` and such, which is the case with `_prefixes`.

This change was intentional, it allows for example to have an action
called `status`, which is an internal method, and that is properly
managed as an action method now. However, it broke Devise due to
overriding `_prefixes`, which is a public method of Action Controller.

To fix, we are simply ensuring we keep `_prefixes` as an internal method
rather than action method, which matches previous behavior for this
particular method/implementation in Devise.

Ref: https://github.com/rails/rails/pull/48699
2023-10-10 11:29:29 -03:00
Carlos Antonio da Silva
218d14a227 Lock ubuntu version to 20.04 to workaround older Ruby build issues
Trying to get the build fully green for now.
2023-10-10 11:29:29 -03:00
Carlos Antonio da Silva
501ae58a25 Lock loofah on Rails <= 5.2
There's some incompatibility issue with loofah there since it uses an
older version of nokogiri, so I'm locking it on those older versions to
try to get a green build again there.
2023-10-10 11:29:29 -03:00
Carlos Antonio da Silva
373d83cc9d Use Bundler 1.x with Ruby <= 2.2
Here we go again.
2023-10-10 11:29:29 -03:00
Carlos Antonio da Silva
fb7faf7466 Fix code to support older versions of Ruby
We still support super old versions, yes, and it doesn't like `ensure`
without a `begin..end` unfortunately.

I plan to remove this support soon, but for now I don't want to stop
supporting it yet.
2023-10-10 11:29:29 -03:00
Carlos Antonio da Silva
9784555304 Merge pull request #5628 from soartec-lab/fix/dedicated_active_support_deprecation
Fixed missing migration to dedicated deprecator
2023-10-10 11:29:29 -03:00
Rafael Mendonça França
13cb6e269d Merge pull request #5599 from etiennebarrie/rails-edge-deprecations
Fix Rails main deprecations
2023-10-10 11:29:29 -03:00
Rafael Mendonça França
a7d64ae313 Merge pull request #5583 from etiennebarrie/deprecator
Use a dedicated ActiveSupport::Deprecation
2023-10-10 11:29:29 -03:00
Carlos Antonio da Silva
34cb23ed9c Fix mocha warnings with hash vs kwargs 2023-10-10 11:29:27 -03:00
Carlos Antonio da Silva
14aa380d80 Update mocha to fix issue with Minitest compatibility layer
There's a number of deprecation warnings to work through related to
mocha updates in v2+, we'll get through those on a separate change.
https://github.com/freerange/mocha/blob/main/RELEASE.md#200

The main issue is with Minitest, fixed in v2.1:
https://github.com/freerange/mocha/blob/main/RELEASE.md#210

Also run `bundle update` on the main Gemfile to update all dependencies
there to latest.
2023-10-10 10:51:46 -03:00
Carlos Antonio da Silva
c4c8fad66c Use Rails 7.1 on main Gemfile and create a new one for 7.0 2023-10-10 10:51:46 -03:00
Carlos Antonio da Silva
4b72064bfc Add missing changelog version [ci skip] 2023-04-03 09:25:06 -03:00
Carlos Antonio da Silva
8b0b849a67 Release v4.9.2 2023-04-03 09:23:02 -03:00
Carlos Antonio da Silva
4f849f4fa9 Bring back `Devise.activerecord51? and deprecate it
Even though this is considered an internal / non-public / nodoc method,
it seems some libraries relied on it internally, causing some breakage.

Known libraries so far are `devise-security` and
`devise-pwned_password`.

Closes #5580
2023-04-03 09:21:56 -03:00
Carlos Antonio da Silva
3926e6d9eb Release v4.9.1 2023-03-31 09:39:17 -03:00
Carlos Antonio da Silva
506eaf495d Merge pull request #5576 from heartcombo/ca-multiple-orms
Improve support for Devise in apps with multiple ORMs loaded
2023-03-30 17:54:30 -03:00
Carlos Antonio da Silva
8dbe5b2fe8 Merge pull request #5573 from heartcombo/ca/failure-app-respect-redirect
Respect redirect status code when recalling the action
2023-03-30 17:29:35 -03:00
Carlos Antonio da Silva
207ddc5127 Improve support for Devise in apps with multiple ORMs loaded
Devise is able to work with a specific ORM, either Active Record or
Mongoid, but nothing stops apps from using multiple ORMs within the same
application -- they just need to pick one to use with Devise. That's
generally determined by the require that is added to the Devise
initializer, that will load up either ORM's extensions so you can call
things like `devise` on your model to set it up.

However, some conditional logic in Devise, more specifically around
dirty tracking, was only considering having Active Record loaded up
after a certain version, to determine which methods to call in parts of
the implementation. In a previous change we refactored all that dirty
tracking code into this `OrmDirtyTracking` module to make it easier to
view all the methods that were being conditionally called, and now we're
repurposing this into a more generic `Orm` module (that's nodoc'ed by
default) so that upon including it, we can conditionally include the
proper dirty tracking extensions but also check whether the including
model is really Active Record or not, so we can trigger the correct
dirty tracking behavior for Mongoid as well if both are loaded on the
same app, whereas previously the Mongoid behavior would always use the
new Active Record behavior, but support may differ.

While we are also working to ensure the latest versions of Mongoid are
fully running with Devise, this should improve the situation by giving
apps with multiple ORMs loaded a chance to rely on some of these Devise
bits of functionality better now that weren't working properly before
without some monkey-patching on their end.

Closes #5539
Closes #4542
2023-03-23 19:16:23 -03:00
Carlos Antonio da Silva
367ea42762 Refactor dirty tracking conditionals for different versions (#5575)
We have an number of conditions due to how dirty tracking changed around
Rails 5.1, that implement methods using one or another method call. I
might need more of this for mongo upgrades based on an initial
investigation, plus this makes the code really hard to reason about
sometimes with these many conditionals.

While I want to drop support for older versions of Rails soon, this
centralization of dirty methods that are used by devise conditionally
simplifies the usage considerably across the board, moves the version
condition to a single place, and will make it easier to refactor later
once we drop older Rails version by simply removing the `devise_*`
versions of the methods, alongside the prefix on the method calls for
the most part, since those methods follow the naming of the newer Rails
versions.
2023-03-23 19:11:11 -03:00
Carlos Antonio da Silva
89a08357d6 Uses the responder redirect_status when recall returns a redirect
It appears some people use the recall functionality with a redirect
response, and Devise starting on version 4.9 was overriding that status
code to the configured `error_status` for better Turbo support, which
broke the redirect functionality / expectation.

While I don't think it's really great usage of the recall functionality,
or at least it was unexpected usage, it's been working like that
basically forever where recalling would use the status code of the
recalled action, so this at least keeps it more consistent with that
behavior by respecting redirects and keeping that response as a redirect
based on the configured status, which should also work with Turbo I
believe, and makes this less of a breaking change.

Closes #5570
Closes #5561 (it was closed previously, but related / closes with an
actual change now.)
2023-03-20 18:18:54 -03:00
Carlos Antonio da Silva
eed51179c7 Add explicit test for respecting the error_status responder config
While introducing this on turbo, looks like no specific test was added,
so this at least covers that a bit.

It needs some conditional checks since not all supported Rails +
Responders version work with the customization, so there's one test for
the hardcoded status version too, which can be removed in the future.
2023-03-20 17:58:48 -03:00
Carlos Antonio da Silva
232c855c54 Fix tests with Rails main
Rails main / 7.1.0.alpha introduced a change to improve typography by
default, by converting all apostrophes to be single quotation marks.
https://github.com/rails/rails/pull/45463

The change caused all our text based matching to fail, this updates the
tests to ensure compatibility.

Model tests were changed to test against the error type & information
rather than the translated string, which I think is an improvement
overall that should make them a little less brittle. I thought of using
[of_kind?] but that isn't available on all Rails versions we currently
support, while `added?` is. The drawback is that `added?` require full
details like the `:confirmation` example which requires the related
attribute that is being confirmed, but that's a small price to pay.

Integration tests were changed to match on a regexp that accepts both
quotes. I could've used a simple `.` to match anything there, but
thought I'd just keep it specific for clarity on what it is really
expected to match there. Plus, since it's integration testing against a
rendered response body, it's better to match the actual text rather than
resort on other ways. (like using I18n directly, etc.)

[of_kind?] https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-of_kind-3F
2023-03-17 10:59:55 -03:00
Carlos Antonio da Silva
afec6655c7 Update bundle 2023-03-17 10:59:51 -03:00
Carlos Antonio da Silva
7d1dc56fdb Merge branch 'ca-replace-refute-assert-not'
Prefer `assert_not*` helpers.

Closes #5158
2023-03-02 19:15:18 -03:00
Carlos Antonio da Silva
890bd9e3b5 Replace usage of assert ! with actual assert_not helper 2023-03-02 18:41:44 -03:00
Carlos Antonio da Silva
1e63c640c0 Update a few other instances that were using refute methods
Prefer assert_not* in general.
2023-03-02 18:40:35 -03:00
tabakazu
8acbdd6d93 Replace matcher refute to assert_not 2023-03-02 18:38:04 -03:00
Carlos Antonio da Silva
400eaf7fbe Remove not used constant
It's only been almost ~10 years since we removed it's usage. :D
dff7891b97
2023-03-01 22:50:56 -03:00
Carlos Antonio da Silva
df8b79a53f Fix added tests for sign_in_after_reset_password per resource class
We can't just "swap" those model properties, as that sets instance vars
on the classes that get reverted to their "previous" value, which ends
up leaving the instance vars set as `nil`. However, our logic for those
model/class properties actually checks for `defined?` as a way to
override them, and delegates up to `Devise` global config if they are
not defined, so leaving instance vars back with `nil` values isn't
enough, we need to actually remove them.

This introduces a new test helper specifically for overriding those
model configs so that we can do proper cleanup.
2023-03-01 22:50:03 -03:00
Carlos Antonio da Silva
ef6c73b221 Merge branch 'feature/password-reset-configuration'
Closes #5429
2023-03-01 22:20:54 -03:00
Carlos Antonio da Silva
c7a719a979 Add changelog for #5429
[ci skip]
2023-03-01 22:20:37 -03:00
Matt Redmond
60c5774ff4 Delegate sign_in_after_reset_password to resource class
Allows resource class scopes to overrides the global configuration for sign in after reset password behaviour.
2023-03-01 22:18:16 -03:00
Peter Goldstein
90f46bac37 Monkeypatch webrat for Nokogiri compatibility
This is an attempt to address the Webrat / Nokogiri compatibility issue
[discussed here]. It monkeypatches Webrat to explicitly add the old
default arguments to the invocation of to_xpath.

Move monkey patch to its own file under test/support/webrat.
I really need to get rid of webrat.

Closes #5475

[discussed here] https://github.com/sparklemotion/nokogiri/issues/2469
2023-03-01 22:06:40 -03:00
Carlos Antonio da Silva
ee8f0f8e83 Fix frozen string in validatable, use multiline string instead. (#5563)
Expand tests to check for the actual validatable exception message

This was raising a `FrozenError` on Ruby < 3 where interpolated strings
were considered frozen. This [changed in Ruby 3], since such strings are
dynamic there's no point in freezing them by default.

The test wasn't catching this because `FrozenError` actually inherits
from `RuntimeError`:

>> FrozenError.ancestors
=> [FrozenError, RuntimeError, StandardError, Exception, Object ...]

So the exception check passed. Now we're also checking for the error
message to ensure it raised the exception we really expected there.

Closes #5465

[changed in Ruby 3] https://bugs.ruby-lang.org/issues/17104

Co-authored-by: Martin <martin@edv-beratung-meier.de>
2023-03-01 19:56:25 -03:00
Carlos Antonio da Silva
41e2db2120 It is not required to copy the views when customizing controllers
It is indeed recommended for consistency, but Rails will be able to find
the views under `devise/` due to inheritance still, so make that a bit
clearer in the readme docs about customizing controllers, explaining
that copying or moving the views is an optional step.

Closes #5526
[ci skip]
2023-02-20 10:26:59 -03:00
Carlos Antonio da Silva
7f419bf99a Release Devise v4.9.0 2023-02-17 11:14:03 -03:00
Carlos Antonio da Silva
44f0fd741f Update copyright year [ci skip]
Closes #5556
2023-02-16 09:10:59 -03:00
Carlos Antonio da Silva
2d655ea46e Merge pull request #5554 from JunichiIto/fix-unhappy-markup
Remove p tag since p tags cannot contain other block elements
2023-02-14 08:58:23 -03:00
Junichi Ito
49ed129c40 Replce p tag with div since p tags cannot contain other block elements 2023-02-14 08:34:26 +09:00
Carlos Antonio da Silva
8e2e3f6fda Merge pull request #5548 from heartcombo/ca-turbo
Integrate with Hotwire/Turbo by configuring error and response statuses
2023-02-09 18:14:01 -03:00
Carlos Antonio da Silva
31c4f31ef4 Tweak comment about overriding Devise.responder
Albeit it's not super recommended, it's possible and even mentioned in
the changelog/wiki in case the app has some additional responder logic
that needs to be applied to Devise across the board.
2023-02-09 08:51:42 -03:00
Carlos Antonio da Silva
8606e1e671 Expand changelog/readme with info about Turbo vs rails-ujs behavior
Explain a bit more about how `data-confirm` and `data-method` need to be
updated to the turbo versions `data-turbo-confirm` and
`data-turbo-method`, respectively. (and depending on its usage.)

[ci skip]
2023-02-07 11:05:53 -03:00
Carlos Antonio da Silva
2df5efcece Add post install message pointing to the changelog and new upgrade guide
There's some additional information in the wiki upgrade guide for those
interested, but most of it is covered in the changelog and should
suffice.

The post install message should help guide people upgrading to make sure
they know what to do in this new version, since some may be using Turbo
out there with custom responders and failure apps and those would have
to be removed in order to use these new changes fully. Hopefully that's
enough of a nudge for them.
2023-02-03 15:41:30 -03:00
Carlos Antonio da Silva
43c349a2fc Point version to v4.9.0.alpha for now
Just want to have something different than the currently released
version to test out more easily. Plus, this is probably going to become
v4.9.0 final soon anyway.
2023-02-03 15:26:24 -03:00
Carlos Antonio da Silva
0d392fa49f Use the released version of responders v3.1.0
Unfortunately we can't enforce the version in the gemspec because
responders only supports Rails 5.2 now, and Devise still supports
previous versions.

We'll drop support for those in a future major release, so for now I'm
not adding any version.

This also adds a warning in case someone is using an older version of
responders and tries to set the error/redirect statuses via Devise, so
that they know what to do (upgrade responders) in that case.
2023-02-03 14:09:42 -03:00
Carlos Antonio da Silva
d0f0853c75 Remove CodeClimate badge
It's not working right now, and we haven't used it in like forever
to drive anything.

Closes #5549

[ci skip]
2023-02-03 11:50:42 -03:00
Carlos Antonio da Silva
88625d488f Use button_to to generate a POST form, disable turbo with OmniAuth
This changes the OmniAuth "sign in" links to use buttons, which can be
wrapped in an actual HTML form with a method POST, making them work
better with and without Turbo in the app. It doesn't require rails/ujs
anymore in case of a non-Turbo app, as it previously did with links +
method=POST.

Turbo is disabled for those OmniAuth buttons, as they simply don't work
trying to follow the redirect to the OmniAuth provider via fetch,
causing CORS issues/errors.
2023-02-01 11:29:17 -03:00
Carlos Antonio da Silva
f08e0ad24a Integrate with Hotwire/Turbo by configuring error and response statuses
Treat `:turbo_stream` request format as a navigational format, much like
HTML, so Devise/responders can work properly.

Allow configuring the `error_status` and `redirect_status` using the
latest responders features, via a new custom Devise responder, so we can
customize the both responses to match Hotwire/Turbo behavior, for
example with `422 Unprocessable Entity` and `303 See Other`,
respectively. The defaults aren't changing in Devise itself (yet), so it
still responds on errors cases with `200 OK`, and redirects on non-GET
requests with `302 Found`, but new apps are generated with the new
statuses and existing apps can opt-in. Please note that these defaults
might change in a future release of Devise.

PRs/Issues references:

https://github.com/heartcombo/devise/pull/5545
https://github.com/heartcombo/devise/pull/5529
https://github.com/heartcombo/devise/pull/5516
https://github.com/heartcombo/devise/pull/5499
https://github.com/heartcombo/devise/pull/5487
https://github.com/heartcombo/devise/pull/5467
https://github.com/heartcombo/devise/pull/5440
https://github.com/heartcombo/devise/pull/5410
https://github.com/heartcombo/devise/pull/5340

https://github.com/heartcombo/devise/issues/5542
https://github.com/heartcombo/devise/issues/5530
https://github.com/heartcombo/devise/issues/5519
https://github.com/heartcombo/devise/issues/5513
https://github.com/heartcombo/devise/issues/5478
https://github.com/heartcombo/devise/issues/5468
https://github.com/heartcombo/devise/issues/5463
https://github.com/heartcombo/devise/issues/5458
https://github.com/heartcombo/devise/issues/5448
https://github.com/heartcombo/devise/issues/5446
https://github.com/heartcombo/devise/issues/5439
2023-01-31 11:02:01 -03:00
Carlos Antonio da Silva
3632ddf674 Remove XML serializer from a couple gemfiles missed previously
It looks like I missed removing it when XMl was replaced with JSON
across our test suite in a793472a3e.
2023-01-31 10:12:24 -03:00
Carlos Antonio da Silva
cddba28945 Bundle update 2023-01-27 17:15:20 -03:00
Carlos Antonio da Silva
032c4476ae Merge branch 'ca-build' 2023-01-19 11:44:25 -03:00
Carlos Antonio da Silva
319d9fa648 Run with the latest rubygems on newer Ruby versions
Rails master on Ruby 2.7/3.0 is failing with the following error:

    Resolving dependencies...
    Could not find compatible versions
    Because every version of rails depends on RubyGems >= 3.3.13
      and Gemfile-rails-main depends on rails >= 0,
      RubyGems >= 3.3.13 is required.
    So, because current RubyGems version is = 3.1.6,
      version solving has failed.

Trying to run with the latest available rubygems to see if that can fix
the problem, but sticking to the "default" rubygems version on older
Ruby versions to avoid build issues there.
2023-01-19 09:58:53 -03:00
Carlos Antonio da Silva
59bedaa1e7 Attempt to get the build running on Ruby 2.2
It appears we're getting a newer version of this multipart-post
dependency, which doesn't work well with Ruby 2.2 by using
`Object.deprecate_constant`, resulting in the following error:

    .../multipart-post-2.2.0/lib/multipart/post/parts.rb:152:in `<top (required)>':
    undefined method `deprecate_constant' for Object:Class (NoMethodError)

Hopefully by locking on a previous version we can just get the build
back to green for now.
2023-01-17 14:47:26 -03:00
Carlos Antonio da Silva
fc1ac76ddf Add support to Ruby 3.2 (no changes needed) 2023-01-17 14:29:38 -03:00
Carlos Antonio da Silva
6d32d2447c Merge pull request #5503 from ak15/main
Fix typo in lockable documentation
2022-06-27 10:37:35 -03:00
Atul Kanswal
d4bf52bdfd Update lockable.rb
Documentation Confusion
2022-06-27 16:28:03 +05:30
Carlos Antonio da Silva
f8d1ea90bc Merge pull request #5484 from heartcombo/ca-build
Fix build
2022-04-22 13:29:19 -03:00
Carlos Antonio da Silva
2fa9303ab3 Use new method to reset CSRF exposed via the request object
This simplifies the logic considerably, as we don't need to reach out to
what seems more internal-ish implementation of Rails with the
interaction between the request and controller objects.

b925880914
2022-04-22 12:56:10 -03:00
Carlos Antonio da Silva
b5172a0cdb Fix csrf cleanup for Rails 7.1 (main)
Rails implemented a CSRF token storage strategy to allow storing the
CSRF tokens outside of the sessios (for example, in an encrypted
cookie), and changed how the value is kept around during the request
cycle, by using a request.env value.

We still want to ensure the final session value is cleaned correctly in
the test, but the implementation needed to change since we can't simply
delete from the session anymore, we need to make sure we call the Rails
methods for resetting the current storage strategy so it works with all
of them.

https://github.com/rails/rails/pull/44283
2022-04-22 11:08:44 -03:00
Carlos Antonio da Silva
e1c53d6580 Check for empty response body on redirect with Rails main (future 7.1)
Rails is no longer returning a message with the response body on
redirects, just an empty body.

https://github.com/rails/rails/pull/44554
2022-04-22 09:30:58 -03:00
Carlos Antonio da Silva
875217d8c1 Only set property for Rails 7, it has been removed on master
https://github.com/rails/rails/pull/44827
2022-04-22 09:17:46 -03:00
Carlos Antonio da Silva
55eabee800 Use https source for github repos with Bundler 1.x
GitHub no longer supports the git:// protocol, which was the default in
Bundler 1.x.

From the build:

    The unauthenticated git protocol on port 9418 is no longer supported.
    Please see https://github.blog/2021-09-01-improving-git-protocol-security-github/
    for more information.
2022-04-22 09:17:46 -03:00
Carlos Antonio da Silva
8d4c3647a7 Update bundle 2022-04-22 09:17:46 -03:00
Carlos Antonio da Silva
700284fc67 Merge pull request #5483 from yysaki/feature/main_branch_url
Update the urls which refer nonexistent master branch name in documentations
2022-04-21 15:22:11 -03:00
yysaki
1542b7da29 Update the urls which refer nonexistent master branch name in documentations 2022-04-21 23:29:30 +09:00
Carlos Antonio da Silva
451ff6d49c Reorganize test matrix & use latest bundler
* Rails and Ruby versions follow the most recent to oldest, except for
  Rails main, so we can keep the Gemfile the first one.
* Excluding specific matrix combinations based on the Gemfile first,
  Ruby version next, and keep the same order (most recent -> oldest)
* Quote all Ruby versions to keep things consistent. It's required for
  the '3.0' version to avoid the float issue where it'd use the latest
  3.x instead.
2022-02-25 14:50:01 -03:00
Carlos Antonio da Silva
542df3634b Merge pull request #5450 from petergoldstein/feature/add_ruby_3_1
Add Ruby 3.1 to CI matrix
2022-02-25 14:39:14 -03:00
Peter Goldstein
3c5acaf531 Add Ruby 3.1 to CI matrix. Lock to Nokogiri < 1.13 for webrat compatibility 2022-02-23 08:37:31 -08:00
Carlos Antonio da Silva
025b1c8734 Add date to v4.8.1 changelog [ci skip] 2021-12-16 08:08:57 -03:00
88 changed files with 1281 additions and 662 deletions

View File

@@ -8,6 +8,7 @@ jobs:
gemfile:
- Gemfile
- gemfiles/Gemfile-rails-main
- gemfiles/Gemfile-rails-7-0
- gemfiles/Gemfile-rails-6-1
- gemfiles/Gemfile-rails-6-0
- gemfiles/Gemfile-rails-5-2
@@ -16,123 +17,187 @@ jobs:
- gemfiles/Gemfile-rails-4-2
- gemfiles/Gemfile-rails-4-1
ruby:
- 2.1
- 2.2
- 2.3
- 2.4
- 2.5
- 2.6
- 2.7
- 3.0
- '3.3'
- '3.2'
- '3.1'
- '3.0'
- '2.7'
- '2.6'
- '2.5'
- '2.4'
- '2.3'
- '2.2'
- '2.1'
env:
- DEVISE_ORM=active_record
- DEVISE_ORM=mongoid
exclude:
- ruby: 2.1
gemfile: Gemfile
- ruby: 2.1
gemfile: gemfiles/Gemfile-rails-6-0
- ruby: 2.1
gemfile: gemfiles/Gemfile-rails-6-1
- ruby: 2.1
gemfile: gemfiles/Gemfile-rails-main
- ruby: 2.1
gemfile: gemfiles/Gemfile-rails-5-2
- ruby: 2.1
gemfile: gemfiles/Gemfile-rails-5-1
- ruby: 2.1
gemfile: gemfiles/Gemfile-rails-5-0
- ruby: 2.2
gemfile: Gemfile
- ruby: 2.2
gemfile: gemfiles/Gemfile-rails-6-0
- ruby: 2.2
gemfile: gemfiles/Gemfile-rails-6-1
- ruby: 2.2
gemfile: gemfiles/Gemfile-rails-main
- ruby: 2.2
gemfile: gemfiles/Gemfile-rails-5-2
- ruby: 2.3
gemfile: Gemfile
- ruby: 2.3
gemfile: gemfiles/Gemfile-rails-6-0
- ruby: 2.3
gemfile: gemfiles/Gemfile-rails-6-1
- ruby: 2.3
gemfile: gemfiles/Gemfile-rails-main
- ruby: 2.4
gemfile: Gemfile
- ruby: 2.4
gemfile: gemfiles/Gemfile-rails-6-0
- ruby: 2.4
gemfile: gemfiles/Gemfile-rails-6-1
- ruby: 2.4
gemfile: gemfiles/Gemfile-rails-main
- ruby: 2.4
gemfile: gemfiles/Gemfile-rails-4-1
- ruby: 2.5
gemfile: gemfiles/Gemfile-rails-4-1
- ruby: 2.5
gemfile: gemfiles/Gemfile-rails-main
- ruby: 2.5
gemfile: Gemfile
- ruby: 2.6
gemfile: gemfiles/Gemfile-rails-4-1
- ruby: 2.6
gemfile: gemfiles/Gemfile-rails-4-2
- ruby: 2.6
gemfile: Gemfile
- ruby: 2.6
gemfile: gemfiles/Gemfile-rails-main
- ruby: 2.7
gemfile: gemfiles/Gemfile-rails-4-1
- ruby: 2.7
gemfile: gemfiles/Gemfile-rails-4-2
- ruby: 2.7
gemfile: gemfiles/Gemfile-rails-5-0
- ruby: 2.7
gemfile: gemfiles/Gemfile-rails-5-1
- ruby: 2.7
gemfile: gemfiles/Gemfile-rails-5-2
- ruby: 3.0
gemfile: gemfiles/Gemfile-rails-4-1
- ruby: 3.0
gemfile: gemfiles/Gemfile-rails-4-2
- ruby: 3.0
gemfile: gemfiles/Gemfile-rails-5-0
- ruby: 3.0
gemfile: gemfiles/Gemfile-rails-5-1
- ruby: 3.0
gemfile: gemfiles/Gemfile-rails-5-2
- env: DEVISE_ORM=mongoid
gemfile: Gemfile
- env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile-rails-5-0
- env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile-rails-5-1
- env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile-rails-5-2
- env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile-rails-6-0
- env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile-rails-6-1
- env: DEVISE_ORM=mongoid
gemfile: Gemfile
- env: DEVISE_ORM=mongoid
gemfile: gemfiles/Gemfile-rails-main
runs-on: ubuntu-latest
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.7' # Rails > 7.1 supports Ruby >= 3.1
- gemfile: gemfiles/Gemfile-rails-main
ruby: '3.0' # Rails > 7.1 supports Ruby >= 3.1
- gemfile: Gemfile
ruby: '2.6'
- gemfile: Gemfile
ruby: '2.5'
- gemfile: Gemfile
ruby: '2.4'
- gemfile: Gemfile
ruby: '2.3'
- gemfile: Gemfile
ruby: '2.2'
- gemfile: Gemfile
ruby: '2.1'
- gemfile: Gemfile
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.6'
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.5'
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.4'
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.3'
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.2'
- gemfile: gemfiles/Gemfile-rails-main
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-main
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-7-0
ruby: '2.6'
- gemfile: gemfiles/Gemfile-rails-7-0
ruby: '2.5'
- gemfile: gemfiles/Gemfile-rails-7-0
ruby: '2.4'
- gemfile: gemfiles/Gemfile-rails-7-0
ruby: '2.3'
- gemfile: gemfiles/Gemfile-rails-7-0
ruby: '2.2'
- gemfile: gemfiles/Gemfile-rails-7-0
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-7-0
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-6-1
ruby: '2.4'
- gemfile: gemfiles/Gemfile-rails-6-1
ruby: '2.3'
- gemfile: gemfiles/Gemfile-rails-6-1
ruby: '2.2'
- gemfile: gemfiles/Gemfile-rails-6-1
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-6-1
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '3.3'
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '3.2'
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '3.1'
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '2.4'
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '2.3'
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '2.2'
- gemfile: gemfiles/Gemfile-rails-6-0
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-6-0
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '3.3'
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '3.2'
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '3.1'
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '3.0'
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '2.7'
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '2.2'
- gemfile: gemfiles/Gemfile-rails-5-2
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-5-2
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-5-1
ruby: '3.3'
- gemfile: gemfiles/Gemfile-rails-5-1
ruby: '3.2'
- gemfile: gemfiles/Gemfile-rails-5-1
ruby: '3.1'
- gemfile: gemfiles/Gemfile-rails-5-1
ruby: '3.0'
- gemfile: gemfiles/Gemfile-rails-5-1
ruby: '2.7'
- gemfile: gemfiles/Gemfile-rails-5-1
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-5-1
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-5-0
ruby: '3.3'
- gemfile: gemfiles/Gemfile-rails-5-0
ruby: '3.2'
- gemfile: gemfiles/Gemfile-rails-5-0
ruby: '3.1'
- gemfile: gemfiles/Gemfile-rails-5-0
ruby: '3.0'
- gemfile: gemfiles/Gemfile-rails-5-0
ruby: '2.7'
- gemfile: gemfiles/Gemfile-rails-5-0
ruby: '2.1'
- gemfile: gemfiles/Gemfile-rails-5-0
env: DEVISE_ORM=mongoid
- gemfile: gemfiles/Gemfile-rails-4-2
ruby: '3.3'
- gemfile: gemfiles/Gemfile-rails-4-2
ruby: '3.2'
- gemfile: gemfiles/Gemfile-rails-4-2
ruby: '3.1'
- gemfile: gemfiles/Gemfile-rails-4-2
ruby: '3.0'
- gemfile: gemfiles/Gemfile-rails-4-2
ruby: '2.7'
- gemfile: gemfiles/Gemfile-rails-4-2
ruby: '2.6'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '3.3'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '3.2'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '3.1'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '3.0'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '2.7'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '2.6'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '2.5'
- gemfile: gemfiles/Gemfile-rails-4-1
ruby: '2.4'
# TODO: lock `ubunty-20.04` due to older Ruby version compatibility, change to `ubuntu-latest` again when dropping older Ruby support.
# https://github.com/ruby/setup-ruby/issues/496#issuecomment-1520662740
runs-on: ubuntu-20.04
env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
steps:
- uses: actions/checkout@v2
- name: Setup Bundler 1.x for Rails 4.x
if: ${{ matrix.gemfile == 'gemfiles/Gemfile-rails-4-1' || matrix.gemfile == 'gemfiles/Gemfile-rails-4-2' }}
- uses: actions/checkout@v3
- name: Setup Bundler 1.x for Rails 4.x and Ruby <= 2.2
if: ${{ matrix.gemfile == 'gemfiles/Gemfile-rails-4-1' || matrix.gemfile == 'gemfiles/Gemfile-rails-4-2' || matrix.ruby <= '2.2' }}
run: echo "BUNDLER_VERSION=1.17.3" >> $GITHUB_ENV
- name: Setup Rubygems version as default for Ruby < 2.5
if: ${{ matrix.ruby < '2.5' }}
run: echo "RUBYGEMS_VERSION=default" >> $GITHUB_ENV
- name: Setup Rubygems version as 3.2.3 for Ruby 2.5
if: ${{ matrix.ruby == '2.5' }}
run: echo "RUBYGEMS_VERSION=3.2.3" >> $GITHUB_ENV
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true # runs bundle install and caches installed gems automatically
bundler: ${{ env.BUNDLER_VERSION || 'latest' }}
bundler: ${{ env.BUNDLER_VERSION || 'default' }}
rubygems: ${{ env.RUBYGEMS_VERSION || 'latest' }}
- uses: supercharge/mongodb-github-action@1.3.0
if: ${{ matrix.env == 'DEVISE_ORM=mongoid' }}
- run: bundle exec rake

View File

@@ -1,4 +1,60 @@
### 4.8.1
### 4.9.4 - 2024-04-10
* enhancements
* Add support for Ruby 3.3. (no changes needed)
* bug fixes
* Respect locale set by controller in failure app. Devise will carry over the current I18n.locale option when triggering authentication, and will wrap the failure app call with it. [#5567](https://github.com/heartcombo/devise/pull/5567)
### 4.9.3 - 2023-10-11
* enhancements
* Add support for Rails 7.1.
* Add `Devise.deprecator` to integrate with new application deprecators in Rails 7.1. (@soartec-lab, @etiennebarrie)
### 4.9.2 - 2023-04-03
* deprecations
* Bring back `Devise.activerecord51?` and deprecate it, in order to avoid breakage with some libraries that apparently relied on it.
### 4.9.1 - 2023-03-31
* enhancements
* Allow resource class scopes to override the global configuration for `sign_in_after_reset_password` behaviour. [#5429](https://github.com/heartcombo/devise/pull/5429) [@mattr](https://github.com/mattr)
* Refactor conditional dirty tracking logic to a centralized module to simplify usage throughout the codebase. [#5575](https://github.com/heartcombo/devise/pull/5575)
* Improve support for Devise in apps with Active Record and Mongoid ORMs loaded, so it does not incorrectly uses new Active Record dirty tracking APIs with a Mongoid Devise model. [#5576](https://github.com/heartcombo/devise/pull/5576)
* bug fixes
* Failure app will respond with configured `redirect_status` instead of `error_status` if the recall app returns a redirect status (300..399) [#5573](https://github.com/heartcombo/devise/pull/5573)
* Fix frozen string exception in validatable. [#5563](https://github.com/heartcombo/devise/pull/5563) [#5465](https://github.com/heartcombo/devise/pull/5465) [@mameier](https://github.com/mameier)
### 4.9.0 - 2023-02-17
* enhancements
* Add support for Ruby 3.1/3.2.
* Add support for Hotwire + Turbo, default in Rails 7+.
* Devise uses the latest `responders` version (v3.1.0 or higher), which allows configuring the status used for validation error responses (`error_status`) and for redirects after POST/PUT/PATCH/DELETE requests (`redirect_status`). For backwards compatibility, Devise keeps `error_status` as `:ok` which returns a `200 OK` response, and `redirect_status` to `:found` which returns a `302 Found` response, but you can configure it to return `422 Unprocessable Entity` and `303 See Other` respectively, to match the behavior expected by Hotwire/Turbo:
```ruby
# config/initializers/devise.rb
Devise.setup do |config|
# ...
config.responder.error_status = :unprocessable_entity
config.responder.redirect_status = :see_other
# ...
end
```
These configs are already generated by default with new apps, and existing apps may opt-in as described above. Trying to set these with an older version of `responders` will issue a warning and have no effect, so please upgrade the `responders` version if you're upgrading Devise for this integration. Note that these defaults may change in future versions of Devise, to better match the Rails + Hotwire/Turbo defaults across the board.
* If you have a custom responder set on your application and expect it to affect Devise as well, you may need to override the Devise responder entirely with `config.responder = MyApplicationResponder`, so that it uses your custom one. The main reason Devise uses a custom responder is to be able to configure the statuses as described above, but you can also change that config on your own responder if you want. Check the `responders` readme for more info on that.
* If you have created a custom responder and/or failure app just to customize responses for better Hotwire/Turbo integration, they should no longer be necessary.
* `:turbo_stream` is now treated as a navigational format, so it works like HTML navigation when using Turbo. Note: if you relied on `:turbo_stream` to be treated as a non-navigational format before, you can reconfigure your `navigational_formats` in the Devise initializer file to exclude it.
* OmniAuth "Sign in with" links were changed to buttons that generate HTML forms with method=POST, instead of using link + method=POST that required rails-ujs to work. Since rails-ujs is no longer the default for new Rails apps, this allows the OmniAuth buttons to work in any scenario, with or without rails-ujs and/or Turbo. This only affects apps that are using the default `devise/shared/_links.html.erb` partial from Devise with OmniAuth enabled.
* The "Cancel my account" button was changed to include the `data-turbo-confirm` option, so that it works with both rails-ujs and Turbo by default.
* Devise does not provide "sign out" links/buttons in its shared views, but if you're using `sign_out_via` with `:delete` (the default), and are using links with `method: :delete`, those need to be updated with `data: { turbo_method: :delete }` instead for Turbo.
* Check [this upgrade guide](https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-[Hotwire-Turbo-integration]) for more detailed information.
### 4.8.1 - 2021-12-16
* enhancements
* Add support for Rails 7.0. Please note that Turbo integration is not fully supported by Devise yet.

View File

@@ -4,14 +4,14 @@ source "https://rubygems.org"
gemspec
gem "rails", "~> 7.0.0"
gem "rails", "~> 7.1.0"
gem "omniauth"
gem "omniauth-oauth2"
gem "rdoc"
gem "rails-controller-testing", github: "rails/rails-controller-testing"
gem "responders", "~> 3.0"
gem "responders", "~> 3.1"
group :test do
gem "omniauth-facebook"
@@ -19,7 +19,7 @@ group :test do
gem "rexml"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do

View File

@@ -1,6 +1,6 @@
GIT
remote: https://github.com/rails/rails-controller-testing.git
revision: 36e84822ee997d69c971f03f3f3759ee4f4bdc37
revision: c203673f8011a7cdc2a8edf995ae6b3eec3417ca
specs:
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
@@ -10,7 +10,7 @@ GIT
PATH
remote: .
specs:
devise (4.8.1)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
@@ -20,209 +20,252 @@ PATH
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.0)
actionpack (= 7.0.0)
activesupport (= 7.0.0)
actioncable (7.1.0)
actionpack (= 7.1.0)
activesupport (= 7.1.0)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.0)
actionpack (= 7.0.0)
activejob (= 7.0.0)
activerecord (= 7.0.0)
activestorage (= 7.0.0)
activesupport (= 7.0.0)
zeitwerk (~> 2.6)
actionmailbox (7.1.0)
actionpack (= 7.1.0)
activejob (= 7.1.0)
activerecord (= 7.1.0)
activestorage (= 7.1.0)
activesupport (= 7.1.0)
mail (>= 2.7.1)
actionmailer (7.0.0)
actionpack (= 7.0.0)
actionview (= 7.0.0)
activejob (= 7.0.0)
activesupport (= 7.0.0)
net-imap
net-pop
net-smtp
actionmailer (7.1.0)
actionpack (= 7.1.0)
actionview (= 7.1.0)
activejob (= 7.1.0)
activesupport (= 7.1.0)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (7.0.0)
actionview (= 7.0.0)
activesupport (= 7.0.0)
rack (~> 2.0, >= 2.2.0)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.2)
actionpack (7.1.0)
actionview (= 7.1.0)
activesupport (= 7.1.0)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.0)
actionpack (= 7.0.0)
activerecord (= 7.0.0)
activestorage (= 7.0.0)
activesupport (= 7.0.0)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
actiontext (7.1.0)
actionpack (= 7.1.0)
activerecord (= 7.1.0)
activestorage (= 7.1.0)
activesupport (= 7.1.0)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.0)
activesupport (= 7.0.0)
actionview (7.1.0)
activesupport (= 7.1.0)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.0)
activesupport (= 7.0.0)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.1.0)
activesupport (= 7.1.0)
globalid (>= 0.3.6)
activemodel (7.0.0)
activesupport (= 7.0.0)
activerecord (7.0.0)
activemodel (= 7.0.0)
activesupport (= 7.0.0)
activestorage (7.0.0)
actionpack (= 7.0.0)
activejob (= 7.0.0)
activerecord (= 7.0.0)
activesupport (= 7.0.0)
activemodel (7.1.0)
activesupport (= 7.1.0)
activerecord (7.1.0)
activemodel (= 7.1.0)
activesupport (= 7.1.0)
timeout (>= 0.4.0)
activestorage (7.1.0)
actionpack (= 7.1.0)
activejob (= 7.1.0)
activerecord (= 7.1.0)
activesupport (= 7.1.0)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.0)
activesupport (7.1.0)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
bcrypt (3.1.16)
base64 (0.1.1)
bcrypt (3.1.19)
bigdecimal (3.1.4)
builder (3.2.4)
concurrent-ruby (1.1.9)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
crass (1.0.6)
erubi (1.10.0)
faraday (1.8.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
multipart-post (>= 1.2, < 3)
date (3.3.3)
drb (2.1.1)
ruby2_keywords
erubi (1.12.0)
faraday (2.7.11)
base64
faraday-net_http (>= 2.0, < 3.1)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
globalid (1.0.0)
activesupport (>= 5.0)
faraday-net_http (3.0.2)
globalid (1.2.1)
activesupport (>= 6.1)
hashie (5.0.0)
i18n (1.8.11)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
jwt (2.3.0)
loofah (2.13.0)
io-console (0.6.0)
irb (1.8.1)
rdoc
reline (>= 0.3.8)
jwt (2.7.1)
loofah (2.21.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
nokogiri (>= 1.12.0)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.2)
method_source (1.0.0)
mini_mime (1.1.2)
mini_portile2 (2.6.1)
minitest (5.15.0)
mocha (1.13.0)
multi_json (1.15.0)
mini_mime (1.1.5)
mini_portile2 (2.8.4)
minitest (5.20.0)
mocha (2.1.0)
ruby2_keywords (>= 0.0.5)
multi_xml (0.6.0)
multipart-post (2.1.1)
nio4r (2.5.8)
nokogiri (1.12.5)
mini_portile2 (~> 2.6.1)
mutex_m (0.1.2)
net-imap (0.4.1)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
net-smtp (0.4.0)
net-protocol
nio4r (2.5.9)
nokogiri (1.15.4)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oauth2 (1.4.7)
faraday (>= 0.8, < 2.0)
oauth2 (2.0.9)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (2.0.4)
rack (>= 1.2, < 4)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
omniauth (2.1.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
rack (>= 2.2.3)
rack-protection
omniauth-facebook (9.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-oauth2 (1.7.2)
oauth2 (~> 1.4)
omniauth (>= 1.9, < 3)
omniauth-oauth2 (1.8.0)
oauth2 (>= 1.4, < 3)
omniauth (~> 2.0)
omniauth-openid (2.0.1)
omniauth (>= 1.0, < 3.0)
rack-openid (~> 1.4.0)
orm_adapter (0.5.0)
racc (1.6.0)
rack (2.2.3)
psych (5.1.0)
stringio
racc (1.7.1)
rack (2.2.8)
rack-openid (1.4.2)
rack (>= 1.1.0)
ruby-openid (>= 2.1.8)
rack-protection (2.1.0)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (7.0.0)
actioncable (= 7.0.0)
actionmailbox (= 7.0.0)
actionmailer (= 7.0.0)
actionpack (= 7.0.0)
actiontext (= 7.0.0)
actionview (= 7.0.0)
activejob (= 7.0.0)
activemodel (= 7.0.0)
activerecord (= 7.0.0)
activestorage (= 7.0.0)
activesupport (= 7.0.0)
rack-protection (3.1.0)
rack (~> 2.2, >= 2.2.4)
rack-session (1.0.1)
rack (< 3)
rack-test (2.1.0)
rack (>= 1.3)
rackup (1.0.0)
rack (< 3)
webrick
rails (7.1.0)
actioncable (= 7.1.0)
actionmailbox (= 7.1.0)
actionmailer (= 7.1.0)
actionpack (= 7.1.0)
actiontext (= 7.1.0)
actionview (= 7.1.0)
activejob (= 7.1.0)
activemodel (= 7.1.0)
activerecord (= 7.1.0)
activestorage (= 7.1.0)
activesupport (= 7.1.0)
bundler (>= 1.15.0)
railties (= 7.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
railties (= 7.1.0)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.2)
loofah (~> 2.3)
railties (7.0.0)
actionpack (= 7.0.0)
activesupport (= 7.0.0)
method_source
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.1.0)
actionpack (= 7.1.0)
activesupport (= 7.1.0)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rake (13.0.6)
rdoc (6.3.3)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
rdoc (6.5.0)
psych (>= 4.0.0)
reline (0.3.9)
io-console (~> 0.5)
responders (3.1.0)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.6)
ruby-openid (2.9.2)
ruby2_keywords (0.0.5)
sqlite3 (1.4.2)
thor (1.1.0)
timecop (0.9.4)
tzinfo (2.0.4)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
sqlite3 (1.6.6)
mini_portile2 (~> 2.8.0)
stringio (3.0.8)
thor (1.2.2)
timecop (0.9.8)
timeout (0.4.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
version_gem (1.1.3)
warden (1.2.9)
rack (>= 2.0.9)
webrat (0.7.3)
nokogiri (>= 1.2.0)
rack (>= 1.0)
rack-test (>= 0.5.3)
websocket-driver (0.7.5)
webrick (1.8.1)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
zeitwerk (2.5.1)
zeitwerk (2.6.12)
PLATFORMS
ruby
DEPENDENCIES
devise!
mocha (~> 1.1)
mocha (~> 2.1)
omniauth
omniauth-facebook
omniauth-oauth2
omniauth-openid
rails (~> 7.0.0)
rails (~> 7.1.0)
rails-controller-testing!
rdoc
responders (~> 3.0)
responders (~> 3.1)
rexml
sqlite3 (~> 1.4)
timecop
webrat (= 0.7.3)
BUNDLED WITH
2.2.33
2.4.5

View File

@@ -1,4 +1,4 @@
Copyright 2020 Rafael França, Leonardo Tegon, Carlos Antônio da Silva.
Copyright 2020-2024 Rafael França, Leonardo Tegon, Carlos Antônio da Silva.
Copyright 2009-2019 Plataformatec.
Permission is hereby granted, free of charge, to any person obtaining

View File

@@ -1,6 +1,4 @@
![Devise Logo](https://raw.github.com/heartcombo/devise/master/devise.png)
[![Code Climate](https://codeclimate.com/github/heartcombo/devise.svg)](https://codeclimate.com/github/heartcombo/devise)
![Devise Logo](https://raw.github.com/heartcombo/devise/main/devise.png)
Devise is a flexible authentication solution for Rails based on Warden. It:
@@ -11,16 +9,16 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
It's composed of 10 modules:
* [Database Authenticatable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/DatabaseAuthenticatable): hashes and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
* [Omniauthable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Omniauthable): adds OmniAuth (https://github.com/omniauth/omniauth) support.
* [Confirmable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Confirmable): sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
* [Recoverable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Recoverable): resets the user password and sends reset instructions.
* [Registerable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Registerable): handles signing up users through a registration process, also allowing them to edit and destroy their account.
* [Rememberable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Rememberable): manages generating and clearing a token for remembering the user from a saved cookie.
* [Trackable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Trackable): tracks sign in count, timestamps and IP address.
* [Timeoutable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Timeoutable): expires sessions that have not been active in a specified period of time.
* [Validatable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Validatable): provides validations of email and password. It's optional and can be customized, so you're able to define your own validations.
* [Lockable](http://www.rubydoc.info/github/heartcombo/devise/master/Devise/Models/Lockable): locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.
* [Database Authenticatable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/DatabaseAuthenticatable): hashes and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
* [Omniauthable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Omniauthable): adds OmniAuth (https://github.com/omniauth/omniauth) support.
* [Confirmable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Confirmable): sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
* [Recoverable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Recoverable): resets the user password and sends reset instructions.
* [Registerable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Registerable): handles signing up users through a registration process, also allowing them to edit and destroy their account.
* [Rememberable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Rememberable): manages generating and clearing a token for remembering the user from a saved cookie.
* [Trackable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Trackable): tracks sign in count, timestamps and IP address.
* [Timeoutable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Timeoutable): expires sessions that have not been active in a specified period of time.
* [Validatable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Validatable): provides validations of email and password. It's optional and can be customized, so you're able to define your own validations.
* [Lockable](http://www.rubydoc.info/github/heartcombo/devise/main/Devise/Models/Lockable): locks an account after a specified number of failed sign-in attempts. Can unlock via email or after a specified time period.
## Table of Contents
@@ -48,7 +46,7 @@ It's composed of 10 modules:
- [Integration tests](#integration-tests)
- [OmniAuth](#omniauth)
- [Configuring multiple models](#configuring-multiple-models)
- [ActiveJob Integration](#activejob-integration)
- [Active Job Integration](#active-job-integration)
- [Password reset tokens and Rails logs](#password-reset-tokens-and-rails-logs)
- [Other ORMs](#other-orms)
- [Rails API mode](#rails-api-mode)
@@ -91,7 +89,7 @@ https://groups.google.com/group/plataformatec-devise
You can view the Devise documentation in RDoc format here:
http://rubydoc.info/github/heartcombo/devise/master/frames
http://rubydoc.info/github/heartcombo/devise/main/frames
If you need to use Devise with previous versions of Rails, you can always run "gem server" from the command line after you install the gem to access the old documentation.
@@ -130,7 +128,7 @@ 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/heartcombo/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 using some of them. If that's the case, you can simulate the same environment using the `BUNDLE_GEMFILE` variable.
Inside the [gemfiles](https://github.com/heartcombo/devise/tree/main/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 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:
```bash
rbenv shell 2.4.2 # or rvm use 2.4.2
@@ -384,7 +382,7 @@ $ rails generate devise:views users
```
If you would like to generate only a few sets of views, like the ones for the `registerable` and `confirmable` module,
you can pass a list of modules to the generator with the `-v` flag.
you can pass a list of views to the generator with the `-v` flag.
```console
$ rails generate devise:views -v registrations confirmations
@@ -412,7 +410,7 @@ If the customization at the views level is not enough, you can customize each co
...
end
```
(Use the -c flag to specify a controller, for example: `rails generate devise:controllers users -c=sessions`)
Use the `-c` flag to specify one or more controllers, for example: `rails generate devise:controllers users -c sessions`)
2. Tell the router to use this controller:
@@ -420,7 +418,7 @@ If the customization at the views level is not enough, you can customize each co
devise_for :users, controllers: { sessions: 'users/sessions' }
```
3. Copy the views from `devise/sessions` to `users/sessions`. Since the controller was changed, it won't use the default views located in `devise/sessions`.
3. Recommended but not required: copy (or move) the views from `devise/sessions` to `users/sessions`. Rails will continue using the views from `devise/sessions` due to inheritance if you skip this step, but having the views matching the controller(s) keeps things consistent.
4. Finally, change or extend the desired controller actions.
@@ -458,7 +456,7 @@ Devise also ships with default routes. If you need to customize them, you should
devise_for :users, path: 'auth', path_names: { sign_in: 'login', sign_out: 'logout', password: 'secret', confirmation: 'verification', unlock: 'unblock', registration: 'register', sign_up: 'cmon_let_me_in' }
```
Be sure to check `devise_for` [documentation](http://www.rubydoc.info/github/heartcombo/devise/master/ActionDispatch/Routing/Mapper%3Adevise_for) for details.
Be sure to check `devise_for` [documentation](http://www.rubydoc.info/github/heartcombo/devise/main/ActionDispatch/Routing/Mapper%3Adevise_for) for details.
If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is create your routes normally and wrap them in a `devise_scope` block in the router:
@@ -476,6 +474,36 @@ Please note: You will still need to add `devise_for` in your routes in order to
devise_for :users, skip: :all
```
### Hotwire/Turbo
Devise integrates with Hotwire/Turbo by treating such requests as navigational, and configuring certain responses for errors and redirects to match the expected behavior. New apps are generated with the following response configuration by default, and existing apps may opt-in by adding the config to their Devise initializers:
```ruby
Devise.setup do |config|
# ...
# When using Devise with Hotwire/Turbo, the http status for error responses
# and some redirects must match the following. The default in Devise for existing
# apps is `200 OK` and `302 Found` respectively, but new apps are generated with
# these new defaults that match Hotwire/Turbo behavior.
# Note: These might become the new default in future versions of Devise.
config.responder.error_status = :unprocessable_entity
config.responder.redirect_status = :see_other
end
```
**Important**: these custom responses require the `responders` gem version to be `3.1.0` or higher, please make sure you update it if you're going to use this configuration. Check [this upgrade guide](https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-[Hotwire-Turbo-integration]) for more info.
_Note_: the above statuses configuration may become the default for Devise in a future release.
There are a couple other changes you might need to make in your app to work with Hotwire/Turbo, if you're migrating from rails-ujs:
* The `data-confirm` option that adds a confirmation modal to buttons/forms before submission needs to change to `data-turbo-confirm`, so that Turbo handles those appropriately.
* The `data-method` option that sets the request method for link submissions needs to change to `data-turbo-method`. This is not necessary for `button_to` or `form`s since Turbo can handle those.
If you're setting up Devise to sign out via `:delete`, and you're using links (instead of buttons wrapped in a form) to sign out with the `method: :delete` option, they will need to be updated as described above. (Devise does not provide sign out links/buttons in its shared views.)
Make sure to inspect your views looking for those, and change appropriately.
### I18n
Devise uses flash messages with I18n, in conjunction with the flash keys :notice and :alert. To customize your app, you can set up your locale file:
@@ -679,7 +707,7 @@ end
### Password reset tokens and Rails logs
If you enable the [Recoverable](http://rubydoc.info/github/heartcombo/devise/master/Devise/Models/Recoverable) module, note that a stolen password reset token could give an attacker access to your application. Devise takes effort to generate random, secure tokens, and stores only token digests in the database, never plaintext. However the default logging behavior in Rails can cause plaintext tokens to leak into log files:
If you enable the [Recoverable](http://rubydoc.info/github/heartcombo/devise/main/Devise/Models/Recoverable) module, note that a stolen password reset token could give an attacker access to your application. Devise takes effort to generate random, secure tokens, and stores only token digests in the database, never plaintext. However the default logging behavior in Rails can cause plaintext tokens to leak into log files:
1. Action Mailer logs the entire contents of all outgoing emails to the DEBUG level. Password reset tokens delivered to users in email will be leaked.
2. Active Job logs all arguments to every enqueued job at the INFO level. If you configure Devise to use `deliver_later` to send password reset emails, password reset tokens will be leaked.
@@ -739,6 +767,6 @@ https://github.com/heartcombo/devise/graphs/contributors
## License
MIT License. Copyright 2020 Rafael França, Leonardo Tegon, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
MIT License. Copyright 2020-2024 Rafael França, Leonardo Tegon, Carlos Antônio da Silva. Copyright 2009-2019 Plataformatec.
The Devise logo is licensed under [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](https://creativecommons.org/licenses/by-nc-nd/4.0/).

View File

@@ -27,6 +27,7 @@ class Devise::ConfirmationsController < DeviseController
set_flash_message!(:notice, :confirmed)
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
else
# TODO: use `error_status` when the default changes to `:unprocessable_entity`.
respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
end
end

View File

@@ -36,7 +36,7 @@ class Devise::PasswordsController < DeviseController
if resource.errors.empty?
resource.unlock_access! if unlockable?(resource)
if Devise.sign_in_after_reset_password
if resource_class.sign_in_after_reset_password
flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
set_flash_message!(:notice, flash_message)
resource.after_database_authentication
@@ -53,7 +53,7 @@ class Devise::PasswordsController < DeviseController
protected
def after_resetting_password_path_for(resource)
Devise.sign_in_after_reset_password ? after_sign_in_path_for(resource) : new_session_path(resource_name)
resource_class.sign_in_after_reset_password ? after_sign_in_path_for(resource) : new_session_path(resource_name)
end
# The path used after sending reset password instructions

View File

@@ -67,7 +67,7 @@ class Devise::RegistrationsController < DeviseController
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
set_flash_message! :notice, :destroyed
yield resource if block_given?
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name), status: Devise.responder.redirect_status }
end
# GET /resource/cancel

View File

@@ -45,7 +45,7 @@ class Devise::SessionsController < DeviseController
end
def auth_options
{ scope: resource_name, recall: "#{controller_path}#new" }
{ scope: resource_name, recall: "#{controller_path}#new", locale: I18n.locale }
end
def translation_scope
@@ -77,7 +77,7 @@ class Devise::SessionsController < DeviseController
# support returning empty response on GET request
respond_to do |format|
format.all { head :no_content }
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name) }
format.any(*navigational_formats) { redirect_to after_sign_out_path_for(resource_name), status: Devise.responder.redirect_status }
end
end
end

View File

@@ -29,6 +29,7 @@ class Devise::UnlocksController < DeviseController
set_flash_message! :notice, :unlocked
respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
else
# TODO: use `error_status` when the default changes to `:unprocessable_entity`.
respond_with_navigational(resource.errors, status: :unprocessable_entity){ render :new }
end
end

View File

@@ -15,6 +15,7 @@ class DeviseController < Devise.parent_controller.constantize
end
prepend_before_action :assert_is_devise_resource!
self.responder = Devise.responder
respond_to :html if mimes_for_respond_to.empty?
# Override prefixes to consider the scoped view.
@@ -32,6 +33,19 @@ class DeviseController < Devise.parent_controller.constantize
end
end
# Override internal methods to exclude `_prefixes` from action methods since
# we override it above.
#
# There was an intentional change in Rails 7.1 that will allow it to become
# an action method because it's a public method of a non-abstract controller,
# but we also can't make this abstract because it can affect potential actions
# defined in the parent controller, so instead we ensure `_prefixes` is going
# to be considered internal. (and thus, won't become an action method.)
# Ref: https://github.com/rails/rails/pull/48699
def self.internal_methods #:nodoc:
super << :_prefixes
end
protected
# Gets the actual resource stored in the instance variable

View File

@@ -4,7 +4,7 @@ module DeviseHelper
# Retain this method for backwards compatibility, deprecated in favor of modifying the
# devise/shared/error_messages partial.
def devise_error_messages!
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
[Devise] `DeviseHelper#devise_error_messages!` is deprecated and will be
removed in the next major version.

View File

@@ -38,6 +38,6 @@
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<div>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %></div>
<%= link_to "Back", :back %>

View File

@@ -1,5 +1,5 @@
<% if resource.errors.any? %>
<div id="error_explanation">
<div id="error_explanation" data-turbo-cache="false">
<h2>
<%= I18n.t("errors.messages.not_saved",
count: resource.errors.count,

View File

@@ -20,6 +20,6 @@
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), data: { turbo: false } %><br />
<% end %>
<% end %>

View File

@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
s.metadata = {
"homepage_uri" => "https://github.com/heartcombo/devise",
"documentation_uri" => "https://rubydoc.info/github/heartcombo/devise",
"changelog_uri" => "https://github.com/heartcombo/devise/blob/master/CHANGELOG.md",
"changelog_uri" => "https://github.com/heartcombo/devise/blob/main/CHANGELOG.md",
"source_code_uri" => "https://github.com/heartcombo/devise",
"bug_tracker_uri" => "https://github.com/heartcombo/devise/issues",
"wiki_uri" => "https://github.com/heartcombo/devise/wiki"
@@ -32,4 +32,11 @@ Gem::Specification.new do |s|
s.add_dependency("bcrypt", "~> 3.0")
s.add_dependency("railties", ">= 4.1.0")
s.add_dependency("responders")
s.post_install_message = %q{
[DEVISE] Please review the [changelog] and [upgrade guide] for more info on Hotwire / Turbo integration.
[changelog] https://github.com/heartcombo/devise/blob/main/CHANGELOG.md
[upgrade guide] https://github.com/heartcombo/devise/wiki/How-To:-Upgrade-to-Devise-4.9.0-%5BHotwire-Turbo-integration%5D
}
end

View File

@@ -2,6 +2,11 @@
source "https://rubygems.org"
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
"https://github.com/#{repo_name}.git"
end
gemspec path: ".."
gem "rails", github: "rails/rails", branch: "4-1-stable"
@@ -16,7 +21,7 @@ group :test do
gem "omniauth-openid"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
gem 'test_after_commit', require: false
end
@@ -33,3 +38,12 @@ end
group :mongoid do
gem "mongoid", "~> 4.0"
end
if RUBY_VERSION < "2.3.0"
# We're getting version 2.2.0 which doesn't play nice with Ruby 2.2, using
# `Object.deprecate_constant` which isn't available.
gem "multipart-post", "2.1.1"
end
# There's a build incompatibility issue with nokogiri and loofah
gem "loofah", "~> 2.20.0"

View File

@@ -2,6 +2,11 @@
source "https://rubygems.org"
git_source(:github) do |repo_name|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
"https://github.com/#{repo_name}.git"
end
gemspec path: ".."
gem "rails", github: "rails/rails", branch: "4-2-stable"
@@ -15,7 +20,7 @@ group :test do
gem "omniauth-openid"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
gem 'test_after_commit', require: false
end
@@ -32,3 +37,12 @@ end
group :mongoid do
gem "mongoid", "~> 4.0"
end
if RUBY_VERSION < "2.3.0"
# We're getting version 2.2.0 which doesn't play nice with Ruby 2.2, using
# `Object.deprecate_constant` which isn't available.
gem "multipart-post", "2.1.1"
end
# There's a build incompatibility issue with nokogiri and loofah
gem "loofah", "~> 2.20.0"

View File

@@ -18,7 +18,7 @@ group :test do
gem "omniauth-openid"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do
@@ -29,3 +29,12 @@ end
# group :mongoid do
# gem "mongoid", "~> 4.0.0"
# end
if RUBY_VERSION < "2.3.0"
# We're getting version 2.2.0 which doesn't play nice with Ruby 2.2, using
# `Object.deprecate_constant` which isn't available.
gem "multipart-post", "2.1.1"
end
# There's a build incompatibility issue with nokogiri and loofah
gem "loofah", "~> 2.20.0"

View File

@@ -16,9 +16,18 @@ group :test do
gem "omniauth-openid"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do
gem "sqlite3", "~> 1.3.6"
end
if RUBY_VERSION < "2.3.0"
# We're getting version 2.2.0 which doesn't play nice with Ruby 2.2, using
# `Object.deprecate_constant` which isn't available.
gem "multipart-post", "2.1.1"
end
# There's a build incompatibility issue with nokogiri and loofah
gem "loofah", "~> 2.20.0"

View File

@@ -16,9 +16,12 @@ group :test do
gem "omniauth-openid"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do
gem "sqlite3", "~> 1.3.6"
end
# There's a build incompatibility issue with nokogiri and loofah
gem "loofah", "~> 2.20.0"

View File

@@ -9,7 +9,7 @@ gem "rdoc"
gem "rails-controller-testing", github: "rails/rails-controller-testing"
gem "responders", "~> 3.0"
gem "responders", "~> 3.1"
group :test do
gem "omniauth-facebook"
@@ -17,7 +17,7 @@ group :test do
gem "rexml"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do

View File

@@ -7,11 +7,15 @@ gem "omniauth"
gem "omniauth-oauth2"
gem "rdoc"
gem "activemodel-serializers-xml", github: "rails/activemodel-serializers-xml"
gem "rails-controller-testing", github: "rails/rails-controller-testing"
gem "responders", "~> 3.0"
gem "responders", "~> 3.1"
if RUBY_VERSION >= "3.1"
gem "net-smtp", require: false
gem "net-imap", require: false
gem "net-pop", require: false
end
group :test do
gem "omniauth-facebook"
@@ -19,7 +23,7 @@ group :test do
gem "rexml"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do

View File

@@ -0,0 +1,38 @@
# frozen_string_literal: true
source "https://rubygems.org"
gemspec path: ".."
gem "rails", "~> 7.0.0"
gem "omniauth"
gem "omniauth-oauth2"
gem "rdoc"
gem "rails-controller-testing", github: "rails/rails-controller-testing"
gem "responders", "~> 3.1"
group :test do
gem "omniauth-facebook"
gem "omniauth-openid"
gem "rexml"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do
gem "sqlite3", "~> 1.4"
end
# platforms :jruby do
# gem "activerecord-jdbc-adapter"
# gem "activerecord-jdbcsqlite3-adapter"
# gem "jruby-openssl"
# end
# TODO:
# group :mongoid do
# gem "mongoid", "~> 4.0.0"
# end

View File

@@ -7,11 +7,9 @@ gem "omniauth"
gem "omniauth-oauth2"
gem "rdoc"
gem "activemodel-serializers-xml", github: "rails/activemodel-serializers-xml"
gem "rails-controller-testing", github: "rails/rails-controller-testing"
gem "responders", "~> 3.0"
gem "responders", "~> 3.1"
group :test do
gem "omniauth-facebook"
@@ -19,7 +17,7 @@ group :test do
gem "rexml"
gem "timecop"
gem "webrat", "0.7.3", require: false
gem "mocha", "~> 1.1", require: false
gem "mocha", "~> 2.1", require: false
end
platforms :ruby do

View File

@@ -13,6 +13,7 @@ module Devise
autoload :Encryptor, 'devise/encryptor'
autoload :FailureApp, 'devise/failure_app'
autoload :OmniAuth, 'devise/omniauth'
autoload :Orm, 'devise/orm'
autoload :ParameterFilter, 'devise/parameter_filter'
autoload :ParameterSanitizer, 'devise/parameter_sanitizer'
autoload :TestHelpers, 'devise/test_helpers'
@@ -23,6 +24,7 @@ module Devise
module Controllers
autoload :Helpers, 'devise/controllers/helpers'
autoload :Rememberable, 'devise/controllers/rememberable'
autoload :Responder, 'devise/controllers/responder'
autoload :ScopedViews, 'devise/controllers/scoped_views'
autoload :SignInOut, 'devise/controllers/sign_in_out'
autoload :StoreLocation, 'devise/controllers/store_location'
@@ -217,7 +219,16 @@ module Devise
# Which formats should be treated as navigational.
mattr_accessor :navigational_formats
@@navigational_formats = ["*/*", :html]
@@navigational_formats = ["*/*", :html, :turbo_stream]
# The default responder used by Devise, used to customize status codes with:
#
# `config.responder.error_status`
# `config.responder.redirect_status`
#
# Can be replaced by a custom application responder.
mattr_accessor :responder
@@responder = Devise::Controllers::Responder
# When set to true, signing out a user signs out all other scopes.
mattr_accessor :sign_out_all_scopes
@@ -297,10 +308,6 @@ module Devise
mattr_accessor :sign_in_after_change_password
@@sign_in_after_change_password = true
def self.activerecord51? # :nodoc:
defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
end
# Default way to set up Devise. Run rails generate devise_install to create
# a fresh initializer with all configuration values.
def self.setup
@@ -513,6 +520,18 @@ module Devise
b.each_byte { |byte| res |= byte ^ l.shift }
res == 0
end
def self.deprecator
@deprecator ||= ActiveSupport::Deprecation.new("5.0", "Devise")
end
def self.activerecord51? # :nodoc:
deprecator.warn <<-DEPRECATION.strip_heredoc
[Devise] `Devise.activerecord51?` is deprecated and will be removed in the next major version.
It is a non-public method that's no longer used internally, but that other libraries have been relying on.
DEPRECATION
defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
end
end
require 'warden'

View File

@@ -46,6 +46,7 @@ module Devise
mappings.unshift mappings.delete(favorite.to_sym) if favorite
mappings.each do |mapping|
opts[:scope] = mapping
opts[:locale] = I18n.locale
warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
end
end
@@ -115,6 +116,7 @@ module Devise
class_eval <<-METHODS, __FILE__, __LINE__ + 1
def authenticate_#{mapping}!(opts = {})
opts[:scope] = :#{mapping}
opts[:locale] = I18n.locale
warden.authenticate!(opts) if !devise_controller? || opts.delete(:force)
end

View File

@@ -0,0 +1,35 @@
# frozen_string_literal: true
module Devise
module Controllers
# Custom Responder to configure default statuses that only apply to Devise,
# and allow to integrate more easily with Hotwire/Turbo.
class Responder < ActionController::Responder
if respond_to?(:error_status=) && respond_to?(:redirect_status=)
self.error_status = :ok
self.redirect_status = :found
else
# TODO: remove this support for older Rails versions, which aren't supported by Turbo
# and/or responders. It won't allow configuring a custom response, but it allows Devise
# to use these methods and defaults across the implementation more easily.
def self.error_status
:ok
end
def self.redirect_status
:found
end
def self.error_status=(*)
warn "[DEVISE] Setting the error status on the Devise responder has no effect with this " \
"version of `responders`, please make sure you're using a newer version. Check the changelog for more info."
end
def self.redirect_status=(*)
warn "[DEVISE] Setting the redirect status on the Devise responder has no effect with this " \
"version of `responders`, please make sure you're using a newer version. Check the changelog for more info."
end
end
end
end
end

View File

@@ -21,7 +21,7 @@ module Devise
# to the set_user method in warden.
# If you are using a custom warden strategy and the timeoutable module, you have to
# set `env["devise.skip_timeout"] = true` in the request to use this method, like we do
# in the sessions controller: https://github.com/heartcombo/devise/blob/master/app/controllers/devise/sessions_controller.rb#L7
# in the sessions controller: https://github.com/heartcombo/devise/blob/main/app/controllers/devise/sessions_controller.rb#L7
#
# Examples:
#
@@ -38,7 +38,7 @@ module Devise
expire_data_after_sign_in!
if options[:bypass]
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
Devise.deprecator.warn(<<-DEPRECATION.strip_heredoc, caller)
[Devise] bypass option is deprecated and it will be removed in future version of Devise.
Please use bypass_sign_in method instead.
Example:

View File

@@ -18,6 +18,11 @@ module Devise
delegate :flash, to: :request
include AbstractController::Callbacks
around_action do |failure_app, action|
I18n.with_locale(failure_app.i18n_locale, &action)
end
def self.call(env)
@respond ||= action(:respond)
@respond.call(env)
@@ -71,7 +76,11 @@ module Devise
end
flash.now[:alert] = i18n_message(:invalid) if is_flashing_format?
self.response = recall_app(warden_options[:recall]).call(request.env)
self.response = recall_app(warden_options[:recall]).call(request.env).tap { |response|
response[0] = Rack::Utils.status_code(
response[0].in?(300..399) ? Devise.responder.redirect_status : Devise.responder.error_status
)
}
end
def redirect
@@ -103,7 +112,7 @@ module Devise
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) }
options[:authentication_keys] = keys.join(I18n.translate(:"support.array.words_connector"))
options[:authentication_keys] = keys.join(I18n.t(:"support.array.words_connector"))
options = i18n_options(options)
I18n.t(:"#{scope}.#{message}", **options)
@@ -112,6 +121,10 @@ module Devise
end
end
def i18n_locale
warden_options[:locale]
end
def redirect_url
if warden_message == :timeout
flash[:timedout] = true if is_flashing_format?
@@ -167,7 +180,7 @@ module Devise
end
def skip_format?
%w(html */*).include? request_format.to_s
%w(html */* turbo_stream).include? request_format.to_s
end
# Choose whether we should respond in an HTTP authentication fashion,

View File

@@ -4,6 +4,11 @@ Warden::Manager.after_authentication do |record, warden, options|
clean_up_for_winning_strategy = !warden.winning_strategy.respond_to?(:clean_up_csrf?) ||
warden.winning_strategy.clean_up_csrf?
if Devise.clean_up_csrf_token_on_authentication && clean_up_for_winning_strategy
warden.request.session.try(:delete, :_csrf_token)
if warden.request.respond_to?(:reset_csrf_token)
# Rails 7.1+
warden.request.reset_csrf_token
else
warden.request.session.try(:delete, :_csrf_token)
end
end
end

View File

@@ -84,6 +84,7 @@ module Devise
end
devise_modules_hook! do
include Devise::Orm
include Devise::Models::Authenticatable
selected_modules.each do |m|

View File

@@ -62,7 +62,7 @@ module Devise
:remember_token, :unconfirmed_email, :failed_attempts, :unlock_token, :locked_at]
include Devise::DeprecatedConstantAccessor
deprecate_constant "BLACKLIST_FOR_SERIALIZATION", "Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION"
deprecate_constant "BLACKLIST_FOR_SERIALIZATION", "Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION", deprecator: Devise.deprecator
included do
class_attribute :devise_modules, instance_writer: false

View File

@@ -48,7 +48,7 @@ module Devise
included do
before_create :generate_confirmation_token, if: :confirmation_required?
after_create :skip_reconfirmation_in_callback!, if: :send_confirmation_notification?
if defined?(ActiveRecord) && self < ActiveRecord::Base # ActiveRecord
if Devise::Orm.active_record?(self) # ActiveRecord
after_commit :send_on_create_confirmation_instructions, on: :create, if: :send_confirmation_notification?
after_commit :send_reconfirmation_instructions, on: :update, if: :reconfirmation_required?
else # Mongoid
@@ -258,44 +258,23 @@ module Devise
generate_confirmation_token && save(validate: false)
end
if Devise.activerecord51?
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
self.email = self.email_in_database
self.confirmation_token = nil
generate_confirmation_token
end
else
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
self.email = self.email_was
self.confirmation_token = nil
generate_confirmation_token
end
def postpone_email_change_until_confirmation_and_regenerate_confirmation_token
@reconfirmation_required = true
self.unconfirmed_email = self.email
self.email = self.devise_email_in_database
self.confirmation_token = nil
generate_confirmation_token
end
if Devise.activerecord51?
def postpone_email_change?
postpone = self.class.reconfirmable &&
will_save_change_to_email? &&
!@bypass_confirmation_postpone &&
self.email.present? &&
(!@skip_reconfirmation_in_callback || !self.email_in_database.nil?)
@bypass_confirmation_postpone = false
postpone
end
else
def postpone_email_change?
postpone = self.class.reconfirmable &&
email_changed? &&
!@bypass_confirmation_postpone &&
self.email.present? &&
(!@skip_reconfirmation_in_callback || !self.email_was.nil?)
@bypass_confirmation_postpone = false
postpone
end
def postpone_email_change?
postpone = self.class.reconfirmable &&
devise_will_save_change_to_email? &&
!@bypass_confirmation_postpone &&
self.email.present? &&
(!@skip_reconfirmation_in_callback || !self.devise_email_in_database.nil?)
@bypass_confirmation_postpone = false
postpone
end
def reconfirmation_required?

View File

@@ -86,7 +86,7 @@ module Devise
# 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.deprecator.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
@@ -128,7 +128,7 @@ module Devise
#
def update_without_password(params, *options)
if options.present?
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
Devise.deprecator.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
@@ -177,16 +177,9 @@ module Devise
encrypted_password[0,29] if encrypted_password
end
if Devise.activerecord51?
# Send notification to user when email changes.
def send_email_changed_notification
send_devise_notification(:email_changed, to: email_before_last_save)
end
else
# Send notification to user when email changes.
def send_email_changed_notification
send_devise_notification(:email_changed, to: email_was)
end
# Send notification to user when email changes.
def send_email_changed_notification
send_devise_notification(:email_changed, to: devise_email_before_last_save)
end
# Send notification to user when password changes.
@@ -205,24 +198,12 @@ module Devise
Devise::Encryptor.digest(self.class, password)
end
if Devise.activerecord51?
def send_email_changed_notification?
self.class.send_email_changed_notification && saved_change_to_email? && !@skip_email_changed_notification
end
else
def send_email_changed_notification?
self.class.send_email_changed_notification && email_changed? && !@skip_email_changed_notification
end
def send_email_changed_notification?
self.class.send_email_changed_notification && devise_saved_change_to_email? && !@skip_email_changed_notification
end
if Devise.activerecord51?
def send_password_change_notification?
self.class.send_password_change_notification && saved_change_to_encrypted_password? && !@skip_password_change_notification
end
else
def send_password_change_notification?
self.class.send_password_change_notification && encrypted_password_changed? && !@skip_password_change_notification
end
def send_password_change_notification?
self.class.send_password_change_notification && devise_saved_change_to_encrypted_password? && !@skip_password_change_notification
end
module ClassMethods

View File

@@ -18,7 +18,7 @@ module Devise
# * +maximum_attempts+: how many attempts should be accepted before blocking the user.
# * +lock_strategy+: lock the user account by :failed_attempts or :none.
# * +unlock_strategy+: unlock the user account by :time, :email, :both or :none.
# * +unlock_in+: the time you want to lock the user after to lock happens. Only available when unlock_strategy is :time or :both.
# * +unlock_in+: the time you want to unlock the user after lock happens. Only available when unlock_strategy is :time or :both.
# * +unlock_keys+: the keys you want to use when locking and unlocking an account
#
module Lockable

View File

@@ -99,24 +99,13 @@ module Devise
send_devise_notification(:reset_password_instructions, token, {})
end
if Devise.activerecord51?
def clear_reset_password_token?
encrypted_password_changed = respond_to?(:will_save_change_to_encrypted_password?) && will_save_change_to_encrypted_password?
authentication_keys_changed = self.class.authentication_keys.any? do |attribute|
respond_to?("will_save_change_to_#{attribute}?") && send("will_save_change_to_#{attribute}?")
end
authentication_keys_changed || encrypted_password_changed
def clear_reset_password_token?
encrypted_password_changed = devise_respond_to_and_will_save_change_to_attribute?(:encrypted_password)
authentication_keys_changed = self.class.authentication_keys.any? do |attribute|
devise_respond_to_and_will_save_change_to_attribute?(attribute)
end
else
def clear_reset_password_token?
encrypted_password_changed = respond_to?(:encrypted_password_changed?) && encrypted_password_changed?
authentication_keys_changed = self.class.authentication_keys.any? do |attribute|
respond_to?("#{attribute}_changed?") && send("#{attribute}_changed?")
end
authentication_keys_changed || encrypted_password_changed
end
authentication_keys_changed || encrypted_password_changed
end
module ClassMethods

View File

@@ -29,13 +29,8 @@ module Devise
base.class_eval do
validates_presence_of :email, if: :email_required?
if Devise.activerecord51?
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?
validates_format_of :email, with: email_regexp, allow_blank: true, if: :email_changed?
end
validates_uniqueness_of :email, allow_blank: true, case_sensitive: true, if: :devise_will_save_change_to_email?
validates_format_of :email, with: email_regexp, allow_blank: true, if: :devise_will_save_change_to_email?
validates_presence_of :password, if: :password_required?
validates_confirmation_of :password, if: :password_required?
@@ -47,7 +42,7 @@ module Devise
unavailable_validations = VALIDATIONS.select { |v| !base.respond_to?(v) }
unless unavailable_validations.empty?
raise "Could not use :validatable module since #{base} does not respond " <<
raise "Could not use :validatable module since #{base} does not respond " \
"to the following methods: #{unavailable_validations.to_sentence}."
end
end

71
lib/devise/orm.rb Normal file
View File

@@ -0,0 +1,71 @@
module Devise
module Orm # :nodoc:
def self.active_record?(model)
defined?(ActiveRecord) && model < ActiveRecord::Base
end
def self.active_record_51?(model)
active_record?(model) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
end
def self.included(model)
if Devise::Orm.active_record_51?(model)
model.include DirtyTrackingNewMethods
else
model.include DirtyTrackingOldMethods
end
end
module DirtyTrackingNewMethods
def devise_email_before_last_save
email_before_last_save
end
def devise_email_in_database
email_in_database
end
def devise_saved_change_to_email?
saved_change_to_email?
end
def devise_saved_change_to_encrypted_password?
saved_change_to_encrypted_password?
end
def devise_will_save_change_to_email?
will_save_change_to_email?
end
def devise_respond_to_and_will_save_change_to_attribute?(attribute)
respond_to?("will_save_change_to_#{attribute}?") && send("will_save_change_to_#{attribute}?")
end
end
module DirtyTrackingOldMethods
def devise_email_before_last_save
email_was
end
def devise_email_in_database
email_was
end
def devise_saved_change_to_email?
email_changed?
end
def devise_saved_change_to_encrypted_password?
encrypted_password_changed?
end
def devise_will_save_change_to_email?
email_changed?
end
def devise_respond_to_and_will_save_change_to_attribute?(attribute)
respond_to?("#{attribute}_changed?") && send("#{attribute}_changed?")
end
end
end
end

View File

@@ -17,6 +17,10 @@ module Devise
app.reload_routes! if Devise.reload_routes
end
initializer "devise.deprecator" do |app|
app.deprecators[:devise] = Devise.deprecator if app.respond_to?(:deprecators)
end
initializer "devise.url_helpers" do
Devise.include_helpers(Devise::Controllers)
end

View File

@@ -26,7 +26,7 @@ rescue LoadError
super
end
def deprecate_constant(const_name, new_constant, message: nil, deprecator: ActiveSupport::Deprecation.instance)
def deprecate_constant(const_name, new_constant, message: nil, deprecator: Devise.deprecator)
class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
class_variable_get(:@@_deprecated_constants)[const_name.to_s] = { new: new_constant, message: message, deprecator: deprecator }
end

View File

@@ -69,7 +69,7 @@ module Devise
scope = resource
resource = deprecated
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
[Devise] sign_in(:#{scope}, resource) on controller tests is deprecated and will be removed from Devise.
Please use sign_in(resource, scope: :#{scope}) instead.
DEPRECATION

View File

@@ -4,7 +4,7 @@ module Devise
module TestHelpers
def self.included(base)
base.class_eval do
ActiveSupport::Deprecation.warn <<-DEPRECATION.strip_heredoc
Devise.deprecator.warn <<-DEPRECATION.strip_heredoc
[Devise] including `Devise::TestHelpers` is deprecated and will be removed from Devise.
For controller tests, please include `Devise::Test::ControllerHelpers` instead.
DEPRECATION

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true
module Devise
VERSION = "4.8.1".freeze
VERSION = "4.9.4".freeze
end

View File

@@ -256,14 +256,14 @@ Devise.setup do |config|
# ==> Navigation configuration
# Lists the formats that should be treated as navigational. Formats like
# :html, should redirect to the sign in page when the user does not have
# :html should redirect to the sign in page when the user does not have
# access, but formats like :xml or :json, should return 401.
#
# If you have any extra navigational formats, like :iphone or :mobile, you
# should add them to the navigational formats lists.
#
# The "*/*" below is required to match Internet Explorer requests.
# config.navigational_formats = ['*/*', :html]
# config.navigational_formats = ['*/*', :html, :turbo_stream]
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :delete
@@ -296,12 +296,14 @@ Devise.setup do |config|
# so you need to do it manually. For the users scope, it would be:
# config.omniauth_path_prefix = '/my_engine/users/auth'
# ==> Turbolinks configuration
# If your app is using Turbolinks, Turbolinks::Controller needs to be included to make redirection work correctly:
#
# ActiveSupport.on_load(:devise_failure_app) do
# include Turbolinks::Controller
# end
# ==> Hotwire/Turbo configuration
# When using Devise with Hotwire/Turbo, the http status for error responses
# and some redirects must match the following. The default in Devise for existing
# apps is `200 OK` and `302 Found` respectively, but new apps are generated with
# these new defaults that match Hotwire/Turbo behavior.
# Note: These might become the new default in future versions of Devise.
config.responder.error_status = :unprocessable_entity
config.responder.redirect_status = :see_other
# ==> Configuration for :registerable

View File

@@ -30,6 +30,6 @@
<h3>Cancel my account</h3>
<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<div>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %></div>
<%= link_to "Back", :back %>

View File

@@ -14,8 +14,8 @@ class HelperMethodsTest < Devise::ControllerTestCase
end
test 'does not respond_to helper or helper_method' do
refute_respond_to @controller.class, :helper
refute_respond_to @controller.class, :helper_method
assert_not_respond_to @controller.class, :helper
assert_not_respond_to @controller.class, :helper_method
end
test 'defines methods like current_user' do

View File

@@ -64,30 +64,30 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
end
test 'proxy authenticate_user! to authenticate with user scope' do
@mock_warden.expects(:authenticate!).with(scope: :user)
@mock_warden.expects(:authenticate!).with({ scope: :user, locale: :en })
@controller.authenticate_user!
end
test 'proxy authenticate_user! options to authenticate with user scope' do
@mock_warden.expects(:authenticate!).with(scope: :user, recall: "foo")
@mock_warden.expects(:authenticate!).with({ scope: :user, recall: "foo", locale: :en })
@controller.authenticate_user!(recall: "foo")
end
test 'proxy authenticate_admin! to authenticate with admin scope' do
@mock_warden.expects(:authenticate!).with(scope: :admin)
@mock_warden.expects(:authenticate!).with({ scope: :admin, locale: :en })
@controller.authenticate_admin!
end
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, locale: :en })
@mock_warden.expects(:authenticate?).with(scope: scope).returns(false)
end
@controller.authenticate_commenter!
end
test 'proxy authenticate_publisher_account! to authenticate with namespaced publisher account scope' do
@mock_warden.expects(:authenticate!).with(scope: :publisher_account)
@mock_warden.expects(:authenticate!).with({ scope: :publisher_account, locale: :en })
@controller.authenticate_publisher_account!
end
@@ -98,7 +98,7 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
test 'proxy admin_signed_in? to authenticatewith admin scope' do
@mock_warden.expects(:authenticate).with(scope: :admin)
refute @controller.admin_signed_in?
assert_not @controller.admin_signed_in?
end
test 'proxy publisher_account_signed_in? to authenticate with namespaced publisher account scope' do
@@ -127,14 +127,14 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
test 'sign in proxy to set_user on warden' do
user = User.new
@mock_warden.expects(:user).returns(nil)
@mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
@mock_warden.expects(:set_user).with(user, { scope: :user }).returns(true)
@controller.sign_in(:user, user)
end
test 'sign in accepts a resource as argument' do
user = User.new
@mock_warden.expects(:user).returns(nil)
@mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
@mock_warden.expects(:set_user).with(user, { scope: :user }).returns(true)
@controller.sign_in(user)
end
@@ -148,7 +148,7 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
test 'sign in again when the user is already in only if force is given' do
user = User.new
@mock_warden.expects(:user).returns(user)
@mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
@mock_warden.expects(:set_user).with(user, { scope: :user }).returns(true)
@controller.sign_in(user, force: true)
end
@@ -269,7 +269,7 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
user = User.new
@controller.session[:user_return_to] = "/foo.bar"
@mock_warden.expects(:user).with(:user).returns(nil)
@mock_warden.expects(:set_user).with(user, scope: :user).returns(true)
@mock_warden.expects(:set_user).with(user, { scope: :user }).returns(true)
@controller.expects(:redirect_to).with("/foo.bar")
@controller.sign_in_and_redirect(user)
end
@@ -277,7 +277,7 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
test 'sign in and redirect uses the configured after sign in path' do
admin = Admin.new
@mock_warden.expects(:user).with(:admin).returns(nil)
@mock_warden.expects(:set_user).with(admin, scope: :admin).returns(true)
@mock_warden.expects(:set_user).with(admin, { scope: :admin }).returns(true)
@controller.expects(:redirect_to).with(admin_root_path)
@controller.sign_in_and_redirect(admin)
end
@@ -319,10 +319,10 @@ class ControllerAuthenticatableTest < Devise::ControllerTestCase
test 'is_flashing_format? is guarded against flash (middleware) not being loaded' do
@controller.request.expects(:respond_to?).with(:flash).returns(false)
refute @controller.is_flashing_format?
assert_not @controller.is_flashing_format?
end
test 'is not a devise controller' do
refute @controller.devise_controller?
assert_not @controller.devise_controller?
end
end

View File

@@ -55,7 +55,7 @@ class HelpersTest < Devise::ControllerTestCase
end
test 'require no authentication tests current mapping' do
@mock_warden.expects(:authenticate?).with(:rememberable, scope: :user).returns(true)
@mock_warden.expects(:authenticate?).with(:rememberable, { scope: :user }).returns(true)
@mock_warden.expects(:user).with(:user).returns(User.new)
@controller.expects(:redirect_to).with(root_path)
@controller.send :require_no_authentication
@@ -71,7 +71,7 @@ class HelpersTest < Devise::ControllerTestCase
end
test 'require no authentication sets a flash message' do
@mock_warden.expects(:authenticate?).with(:rememberable, scope: :user).returns(true)
@mock_warden.expects(:authenticate?).with(:rememberable, { scope: :user }).returns(true)
@mock_warden.expects(:user).with(:user).returns(User.new)
@controller.expects(:redirect_to).with(root_path)
@controller.send :require_no_authentication
@@ -121,7 +121,7 @@ class HelpersTest < Devise::ControllerTestCase
MyController.send(:public, :navigational_formats)
swap Devise, navigational_formats: ['*/*', :html] do
refute @controller.navigational_formats.include?("*/*")
assert_not @controller.navigational_formats.include?("*/*")
end
MyController.send(:protected, :navigational_formats)

View File

@@ -71,8 +71,8 @@ class DeviseTest < ActiveSupport::TestCase
test 'add new module using the helper method' do
Devise.add_module(:coconut)
assert_equal 1, Devise::ALL.select { |v| v == :coconut }.size
refute Devise::STRATEGIES.include?(:coconut)
refute defined?(Devise::Models::Coconut)
assert_not Devise::STRATEGIES.include?(:coconut)
assert_not defined?(Devise::Models::Coconut)
Devise::ALL.delete(:coconut)
Devise.add_module(:banana, strategy: :fruits)
@@ -88,11 +88,11 @@ class DeviseTest < ActiveSupport::TestCase
test 'should complain when comparing empty or different sized passes' do
[nil, ""].each do |empty|
refute Devise.secure_compare(empty, "something")
refute Devise.secure_compare("something", empty)
refute Devise.secure_compare(empty, empty)
assert_not Devise.secure_compare(empty, "something")
assert_not Devise.secure_compare("something", empty)
assert_not Devise.secure_compare(empty, empty)
end
refute Devise.secure_compare("size_1", "size_four")
assert_not Devise.secure_compare("size_1", "size_four")
end
test 'Devise.email_regexp should match valid email addresses' do
@@ -106,4 +106,10 @@ class DeviseTest < ActiveSupport::TestCase
assert_no_match Devise.email_regexp, email
end
end
test 'Devise.activerecord51? deprecation' do
assert_deprecated("`Devise.activerecord51?` is deprecated", Devise.deprecator) do
Devise.activerecord51?
end
end
end

View File

@@ -200,6 +200,13 @@ class FailureTest < ActiveSupport::TestCase
assert_equal 'User Steve does not exist', @request.flash[:alert]
end
test 'respects the i18n locale passed via warden options when redirecting' do
call_failure('warden' => OpenStruct.new(message: :invalid), 'warden.options' => { locale: :"pt-BR" })
assert_equal 'Email ou senha inválidos.', @request.flash[:alert]
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
end
test 'uses the proxy failure message as string' do
call_failure('warden' => OpenStruct.new(message: 'Hello world'))
assert_equal 'Hello world', @request.flash[:alert]
@@ -213,9 +220,13 @@ class FailureTest < ActiveSupport::TestCase
test 'set up a default message' do
call_failure
assert_match(/You are being/, @response.last.body)
assert_match(/redirected/, @response.last.body)
assert_match(/users\/sign_in/, @response.last.body)
if Devise::Test.rails71_and_up?
assert_empty @response.last.body
else
assert_match(/You are being/, @response.last.body)
assert_match(/redirected/, @response.last.body)
assert_match(/users\/sign_in/, @response.last.body)
end
end
test 'works for any navigational format' do
@@ -280,6 +291,12 @@ class FailureTest < ActiveSupport::TestCase
assert_match '<error>Invalid Email or password.</error>', @response.third.body
end
test 'respects the i18n locale passed via warden options when responding to HTTP request' do
call_failure('formats' => Mime[:json], 'warden' => OpenStruct.new(message: :invalid), 'warden.options' => { locale: :"pt-BR" })
assert_equal %({"error":"Email ou senha inválidos."}), @response.third.body
end
context 'on ajax call' do
context 'when http_authenticatable_on_xhr is false' do
test 'dont return 401 with navigational formats' do
@@ -367,6 +384,71 @@ class FailureTest < ActiveSupport::TestCase
end
end
end
test 'respects the i18n locale passed via warden options when recalling original controller' do
env = {
"warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in", locale: :"pt-BR" },
"devise.mapping" => Devise.mappings[:user],
"warden" => stub_everything
}
call_failure(env)
assert_includes @response.third.body, '<h2>Log in</h2>'
assert_includes @response.third.body, 'Email ou senha inválidos.'
end
# TODO: remove conditional/else when supporting only responders 3.1+
if ActionController::Responder.respond_to?(:error_status=)
test 'respects the configured responder `error_status` for the status code' do
swap Devise.responder, error_status: :unprocessable_entity do
env = {
"warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in" },
"devise.mapping" => Devise.mappings[:user],
"warden" => stub_everything
}
call_failure(env)
assert_equal 422, @response.first
assert_includes @response.third.body, 'Invalid Email or password.'
end
end
test 'respects the configured responder `redirect_status` if the recall app returns a redirect status code' do
swap Devise.responder, redirect_status: :see_other do
env = {
"warden.options" => { recall: "devise/registrations#cancel", attempted_path: "/users/cancel" },
"devise.mapping" => Devise.mappings[:user],
"warden" => stub_everything
}
call_failure(env)
assert_equal 303, @response.first
end
end
else
test 'uses default hardcoded responder `error_status` for the status code since responders version does not support configuring it' do
env = {
"warden.options" => { recall: "devise/sessions#new", attempted_path: "/users/sign_in" },
"devise.mapping" => Devise.mappings[:user],
"warden" => stub_everything
}
call_failure(env)
assert_equal 200, @response.first
assert_includes @response.third.body, 'Invalid Email or password.'
end
test 'users default hardcoded responder `redirect_status` for the status code since responders version does not support configuring it' do
env = {
"warden.options" => { recall: "devise/registrations#cancel", attempted_path: "/users/cancel" },
"devise.mapping" => Devise.mappings[:user],
"warden" => stub_everything
}
call_failure(env)
assert_equal 302, @response.first
end
end
end
context "Lazy loading" do
@@ -374,6 +456,7 @@ class FailureTest < ActiveSupport::TestCase
assert_equal "yes it does", Devise::FailureApp.new.lazy_loading_works?
end
end
context "Without Flash Support" do
test "returns to the default redirect location without a flash message" do
call_failure request_klass: RequestWithoutFlashSupport

View File

@@ -6,7 +6,7 @@ class AuthenticationSanityTest < Devise::IntegrationTest
test 'sign in should not run model validations' do
sign_in_as_user
refute User.validations_performed
assert_not User.validations_performed
end
test 'home should be accessible without sign in' do
@@ -18,13 +18,13 @@ class AuthenticationSanityTest < Devise::IntegrationTest
test 'sign in as user should not authenticate admin scope' do
sign_in_as_user
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'sign in as admin should not authenticate user scope' do
sign_in_as_admin
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'sign in as both user and admin at same time' do
@@ -39,7 +39,7 @@ class AuthenticationSanityTest < Devise::IntegrationTest
sign_in_as_user
sign_in_as_admin
delete destroy_user_session_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert warden.authenticated?(:admin)
end
end
@@ -50,7 +50,7 @@ class AuthenticationSanityTest < Devise::IntegrationTest
sign_in_as_admin
delete destroy_admin_session_path
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
assert warden.authenticated?(:user)
end
end
@@ -61,8 +61,8 @@ class AuthenticationSanityTest < Devise::IntegrationTest
sign_in_as_admin
delete destroy_user_session_path
refute warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
end
end
@@ -72,21 +72,21 @@ class AuthenticationSanityTest < Devise::IntegrationTest
sign_in_as_admin
delete destroy_admin_session_path
refute warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
assert_not warden.authenticated?(:user)
end
end
test 'not signed in as admin should not be able to access admins actions' do
get admins_path
assert_redirected_to new_admin_session_path
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'signed in as user should not be able to access admins actions' do
sign_in_as_user
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
get admins_path
assert_redirected_to new_admin_session_path
@@ -95,7 +95,7 @@ class AuthenticationSanityTest < Devise::IntegrationTest
test 'signed in as admin should be able to access admin actions' do
sign_in_as_admin
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
get admins_path
@@ -123,7 +123,7 @@ class AuthenticationSanityTest < Devise::IntegrationTest
get root_path
assert_contain 'Signed out successfully'
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'unauthenticated admin set message on sign out' do
@@ -146,13 +146,13 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'not signed in should not be able to access private route (authenticate denied)' do
get private_path
assert_redirected_to new_admin_session_path
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'signed in as user should not be able to access private route restricted to admins (authenticate denied)' do
sign_in_as_user
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
get private_path
assert_redirected_to new_admin_session_path
end
@@ -160,7 +160,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as admin should be able to access private route restricted to admins (authenticate accepted)' do
sign_in_as_admin
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
get private_path
@@ -172,7 +172,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as inactive admin should not be able to access private/active route restricted to active admins (authenticate denied)' do
sign_in_as_admin(active: false)
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert_raises ActionController::RoutingError do
get "/private/active"
@@ -182,7 +182,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as active admin should be able to access private/active route restricted to active admins (authenticate accepted)' do
sign_in_as_admin(active: true)
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
get private_active_path
@@ -194,7 +194,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as admin should get admin dashboard (authenticated accepted)' do
sign_in_as_admin
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
get dashboard_path
@@ -206,7 +206,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as user should get user dashboard (authenticated accepted)' do
sign_in_as_user
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
get dashboard_path
@@ -224,7 +224,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as inactive admin should not be able to access dashboard/active route restricted to active admins (authenticated denied)' do
sign_in_as_admin(active: false)
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert_raises ActionController::RoutingError do
get "/dashboard/active"
@@ -234,7 +234,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in as active admin should be able to access dashboard/active route restricted to active admins (authenticated accepted)' do
sign_in_as_admin(active: true)
assert warden.authenticated?(:admin)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
get dashboard_active_path
@@ -246,7 +246,7 @@ class AuthenticationRoutesRestrictions < Devise::IntegrationTest
test 'signed in user should not see unauthenticated page (unauthenticated denied)' do
sign_in_as_user
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
assert_raises ActionController::RoutingError do
get join_path
@@ -273,6 +273,15 @@ class AuthenticationRedirectTest < Devise::IntegrationTest
assert_contain 'You need to sign in or sign up before continuing.'
end
test 'redirect from warden respects i18n locale set at the controller' do
get admins_path(locale: "pt-BR")
assert_redirected_to new_admin_session_path
follow_redirect!
assert_contain 'Para continuar, faça login ou registre-se.'
end
test 'redirect to default url if no other was configured' do
sign_in_as_user
assert_template 'home/index'
@@ -346,10 +355,18 @@ class AuthenticationSessionTest < Devise::IntegrationTest
test 'refreshes _csrf_token' do
swap ApplicationController, allow_forgery_protection: true do
get new_user_session_path
token = request.session[:_csrf_token]
token_from_session = request.session[:_csrf_token]
if Devise::Test.rails71_and_up?
token_from_env = request.env["action_controller.csrf_token"]
end
sign_in_as_user
assert_not_equal request.session[:_csrf_token], token
assert_not_equal request.session[:_csrf_token], token_from_session
if Devise::Test.rails71_and_up?
assert_not_equal request.env["action_controller.csrf_token"], token_from_env
end
end
end
@@ -389,7 +406,7 @@ class AuthenticationWithScopedViewsTest < Devise::IntegrationTest
end
assert_match %r{Special user view}, response.body
assert !Devise::PasswordsController.scoped_views?
assert_not Devise::PasswordsController.scoped_views?
ensure
Devise::SessionsController.send :remove_instance_variable, :@scoped_views
end
@@ -416,13 +433,13 @@ class AuthenticationOthersTest < Devise::IntegrationTest
test 'handles unverified requests gets rid of caches' do
swap ApplicationController, allow_forgery_protection: true do
post exhibit_user_url(1)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
sign_in_as_user
assert warden.authenticated?(:user)
post exhibit_user_url(1)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert_equal "User is not authenticated", response.body
end
end
@@ -477,7 +494,7 @@ class AuthenticationOthersTest < Devise::IntegrationTest
test 'uses the mapping from router' do
sign_in_as_user visit: "/as/sign_in"
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'sign in with json format returns json response' do
@@ -519,7 +536,7 @@ class AuthenticationOthersTest < Devise::IntegrationTest
sign_in_as_user
delete destroy_user_session_path(format: 'json')
assert_response :no_content
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'sign out with non-navigational format via XHR does not redirect' do
@@ -527,7 +544,7 @@ class AuthenticationOthersTest < Devise::IntegrationTest
sign_in_as_admin
get destroy_sign_out_via_get_session_path, xhr: true, headers: { "HTTP_ACCEPT" => "application/json,text/javascript,*/*" } # NOTE: Bug is triggered by combination of XHR and */*.
assert_response :no_content
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -537,7 +554,7 @@ class AuthenticationOthersTest < Devise::IntegrationTest
sign_in_as_user
delete destroy_user_session_path, xhr: true, headers: { "HTTP_ACCEPT" => "text/html,*/*" }
assert_response :redirect
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
end
@@ -547,7 +564,7 @@ class AuthenticationKeysTest < Devise::IntegrationTest
swap Devise, authentication_keys: [:subdomain] do
sign_in_as_user
assert_contain "Invalid Subdomain or password."
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -564,7 +581,7 @@ class AuthenticationRequestKeysTest < Devise::IntegrationTest
host! 'foo.bar.baz'
swap Devise, request_keys: [:subdomain] do
User.expects(:find_for_authentication).with(subdomain: 'foo', email: 'user@test.com').returns(create_user)
User.expects(:find_for_authentication).with({ subdomain: 'foo', email: 'user@test.com' }).returns(create_user)
sign_in_as_user
assert warden.authenticated?(:user)
end
@@ -576,7 +593,7 @@ class AuthenticationRequestKeysTest < Devise::IntegrationTest
sign_in_as_user
end
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -586,7 +603,7 @@ class AuthenticationRequestKeysTest < Devise::IntegrationTest
swap Devise, request_keys: [:subdomain] do
sign_in_as_user
assert_contain "Invalid Email or password."
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -609,7 +626,7 @@ class AuthenticationSignOutViaTest < Devise::IntegrationTest
test 'allow sign out via delete when sign_out_via provides only delete' do
sign_in!(:sign_out_via_delete)
delete destroy_sign_out_via_delete_session_path
refute warden.authenticated?(:sign_out_via_delete)
assert_not warden.authenticated?(:sign_out_via_delete)
end
test 'do not allow sign out via get when sign_out_via provides only delete' do
@@ -623,7 +640,7 @@ class AuthenticationSignOutViaTest < Devise::IntegrationTest
test 'allow sign out via post when sign_out_via provides only post' do
sign_in!(:sign_out_via_post)
post destroy_sign_out_via_post_session_path
refute warden.authenticated?(:sign_out_via_post)
assert_not warden.authenticated?(:sign_out_via_post)
end
test 'do not allow sign out via get when sign_out_via provides only post' do
@@ -637,13 +654,13 @@ class AuthenticationSignOutViaTest < Devise::IntegrationTest
test 'allow sign out via delete when sign_out_via provides delete and post' do
sign_in!(:sign_out_via_delete_or_post)
delete destroy_sign_out_via_delete_or_post_session_path
refute warden.authenticated?(:sign_out_via_delete_or_post)
assert_not warden.authenticated?(:sign_out_via_delete_or_post)
end
test 'allow sign out via post when sign_out_via provides delete and post' do
sign_in!(:sign_out_via_delete_or_post)
post destroy_sign_out_via_delete_or_post_session_path
refute warden.authenticated?(:sign_out_via_delete_or_post)
assert_not warden.authenticated?(:sign_out_via_delete_or_post)
end
test 'do not allow sign out via get when sign_out_via provides delete and post' do

View File

@@ -43,12 +43,12 @@ class ConfirmationTest < Devise::IntegrationTest
test 'user with valid confirmation token should not be able to confirm an account after the token has expired' do
swap Devise, confirm_within: 3.days do
user = create_user(confirm: false, confirmation_sent_at: 4.days.ago)
refute user.confirmed?
assert_not user.confirmed?
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_have_selector '#error_explanation'
assert_contain %r{needs to be confirmed within 3 days}
refute user.reload.confirmed?
assert_not user.reload.confirmed?
assert_current_url "/users/confirmation?confirmation_token=#{user.raw_confirmation_token}"
end
end
@@ -86,7 +86,7 @@ class ConfirmationTest < Devise::IntegrationTest
test 'user with valid confirmation token should be able to confirm an account before the token has expired' do
swap Devise, confirm_within: 3.days do
user = create_user(confirm: false, confirmation_sent_at: 2.days.ago)
refute user.confirmed?
assert_not user.confirmed?
visit_user_confirmation_with_token(user.raw_confirmation_token)
assert_contain 'Your email address has been successfully confirmed.'
@@ -132,7 +132,7 @@ class ConfirmationTest < Devise::IntegrationTest
sign_in_as_user(confirm: false)
assert_contain 'You have to confirm your email address before continuing'
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -143,7 +143,7 @@ class ConfirmationTest < Devise::IntegrationTest
end
assert_contain 'Invalid Email or password'
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -178,13 +178,13 @@ class ConfirmationTest < Devise::IntegrationTest
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"
assert_contain %r{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"
assert_contain %r{Confirmation token can[']t be blank}
end
test "should not be able to confirm user with blank confirmation token" do
@@ -193,7 +193,7 @@ class ConfirmationTest < Devise::IntegrationTest
visit_user_confirmation_with_token("")
assert_contain "Confirmation token can't be blank"
assert_contain %r{Confirmation token can[']t be blank}
end
test "should not be able to confirm user with nil confirmation token" do
@@ -202,7 +202,7 @@ class ConfirmationTest < Devise::IntegrationTest
visit_user_confirmation_with_token(nil)
assert_contain "Confirmation token can't be blank"
assert_contain %r{Confirmation token can[']t be blank}
end
test 'error message is configurable by resource name' do
@@ -308,7 +308,7 @@ class ConfirmationOnChangeTest < Devise::IntegrationTest
assert_contain 'Your email address has been successfully confirmed.'
assert_current_url '/admin_area/sign_in'
assert admin.reload.confirmed?
refute admin.reload.pending_reconfirmation?
assert_not admin.reload.pending_reconfirmation?
end
test 'admin with previously valid confirmation token should not be able to confirm email after email changed again' do
@@ -330,7 +330,7 @@ class ConfirmationOnChangeTest < Devise::IntegrationTest
assert_contain 'Your email address has been successfully confirmed.'
assert_current_url '/admin_area/sign_in'
assert admin.reload.confirmed?
refute admin.reload.pending_reconfirmation?
assert_not admin.reload.pending_reconfirmation?
end
test 'admin email should be unique also within unconfirmed_email' do

View File

@@ -21,7 +21,7 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest
fill_in 'email', with: 'foo@bar.com'
end
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -43,14 +43,14 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest
fill_in 'email', with: ' foo@bar.com '
end
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
test 'sign in should not authenticate if not using proper authentication keys' do
swap Devise, authentication_keys: [:username] do
sign_in_as_user
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -61,7 +61,7 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest
end
assert_contain 'Invalid email address'
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
end
@@ -71,7 +71,7 @@ class DatabaseAuthenticationTest < Devise::IntegrationTest
end
assert_contain 'Invalid Email or password'
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'when in paranoid mode and without a valid e-mail' do

View File

@@ -6,7 +6,7 @@ class HttpAuthenticationTest < Devise::IntegrationTest
test 'sign in with HTTP should not run model validations' do
sign_in_as_new_user_with_http
refute User.validations_performed
assert_not User.validations_performed
end
test 'handles unverified requests gets rid of caches but continues signed in' do

View File

@@ -87,7 +87,7 @@ class LockTest < Devise::IntegrationTest
assert_current_url "/users/sign_in"
assert_contain 'Your account has been unlocked successfully. Please sign in to continue.'
refute user.reload.access_locked?
assert_not user.reload.access_locked?
end
test "user should not send a new e-mail if already locked" do

View File

@@ -52,7 +52,7 @@ class OmniauthableIntegrationTest < Devise::IntegrationTest
follow_redirect!
assert warden.authenticated?(:user)
refute User.validations_performed
assert_not User.validations_performed
end
end
@@ -87,7 +87,7 @@ class OmniauthableIntegrationTest < Devise::IntegrationTest
assert_current_url "/"
assert_contain "You have signed up successfully."
assert_contain "Hello User user@example.com"
refute session["devise.facebook_data"]
assert_not session["devise.facebook_data"]
end
test "cleans up session on cancel" do
@@ -98,7 +98,7 @@ class OmniauthableIntegrationTest < Devise::IntegrationTest
assert session["devise.facebook_data"]
visit "/users/cancel"
assert !session["devise.facebook_data"]
assert_not session["devise.facebook_data"]
end
test "cleans up session on sign in" do
@@ -109,7 +109,7 @@ class OmniauthableIntegrationTest < Devise::IntegrationTest
assert session["devise.facebook_data"]
sign_in_as_user
assert !session["devise.facebook_data"]
assert_not session["devise.facebook_data"]
end
test "sign in and send remember token if configured" do
@@ -128,13 +128,17 @@ class OmniauthableIntegrationTest < Devise::IntegrationTest
test "generates a link to authenticate with provider" do
visit "/users/sign_in"
assert_select "a[href=?][data-method='post']", "/users/auth/facebook", text: "Sign in with FaceBook"
assert_select "form[action=?][method=post]", "/users/auth/facebook" do
assert_select "input[type=submit][value=?]", "Sign in with FaceBook"
end
end
test "generates a proper link when SCRIPT_NAME is set" do
header 'SCRIPT_NAME', '/q'
visit "/users/sign_in"
assert_select "a[href=?][data-method='post']", "/q/users/auth/facebook", text: "Sign in with FaceBook"
assert_select "form[action=?][method=post]", "/q/users/auth/facebook" do
assert_select "input[type=submit][value=?]", "Sign in with FaceBook"
end
end
test "handles callback error parameter according to the specification" do

View File

@@ -12,7 +12,7 @@ class PasswordTest < Devise::IntegrationTest
def request_forgot_password(&block)
visit_new_password_path
assert_response :success
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
fill_in 'email', with: 'user@test.com'
yield if block_given?
@@ -160,7 +160,7 @@ class PasswordTest < Devise::IntegrationTest
assert_current_url '/users/password'
assert_have_selector '#error_explanation'
assert_contain %r{Reset password token(.*)invalid}
refute user.reload.valid_password?('987654321')
assert_not user.reload.valid_password?('987654321')
end
test 'not authenticated user with valid reset password token but invalid password should not be able to change their password' do
@@ -173,8 +173,8 @@ class PasswordTest < Devise::IntegrationTest
assert_response :success
assert_current_url '/users/password'
assert_have_selector '#error_explanation'
assert_contain "Password confirmation doesn't match Password"
refute user.reload.valid_password?('987654321')
assert_contain %r{Password confirmation doesn[']t match Password}
assert_not user.reload.valid_password?('987654321')
end
test 'not authenticated user with valid data should be able to change their password' do
@@ -194,7 +194,7 @@ class PasswordTest < Devise::IntegrationTest
reset_password { fill_in 'Confirm new password', with: 'other_password' }
assert_response :success
assert_have_selector '#error_explanation'
refute user.reload.valid_password?('987654321')
assert_not user.reload.valid_password?('987654321')
reset_password visit: false
assert_contain 'Your password has been changed successfully.'
@@ -218,7 +218,32 @@ class PasswordTest < Devise::IntegrationTest
assert_contain 'Your password has been changed successfully.'
assert_not_contain 'You are now signed in.'
assert_equal new_user_session_path, @request.path
assert !warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
test 'does not sign in user automatically after changing its password if resource_class.sign_in_after_reset_password is false' do
swap_model_config User, sign_in_after_reset_password: false do
create_user
request_forgot_password
reset_password
assert_contain 'Your password has been changed successfully'
assert_not_contain 'You are now signed in.'
assert_equal new_user_session_path, @request.path
assert_not warden.authenticated?(:user)
end
end
test 'sign in user automatically after changing its password if resource_class.sign_in_after_reset_password is true' do
swap Devise, sign_in_after_reset_password: false do
swap_model_config User, sign_in_after_reset_password: true do
create_user
request_forgot_password
reset_password
assert warden.authenticated?(:user)
end
end
end
@@ -232,7 +257,7 @@ class PasswordTest < Devise::IntegrationTest
assert_contain 'Your password has been changed successfully.'
assert_not_contain 'You are now signed in.'
assert_equal new_user_session_path, @request.path
assert !warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
end
@@ -244,7 +269,7 @@ class PasswordTest < Devise::IntegrationTest
reset_password
assert_contain 'Your password has been changed successfully.'
assert !user.reload.access_locked?
assert_not user.reload.access_locked?
assert warden.authenticated?(:user)
end
end
@@ -256,7 +281,7 @@ class PasswordTest < Devise::IntegrationTest
reset_password
assert_contain 'Your password has been changed successfully.'
assert !user.reload.access_locked?
assert_not user.reload.access_locked?
assert warden.authenticated?(:user)
end
end

View File

@@ -66,11 +66,11 @@ class RegistrationTest < Devise::IntegrationTest
assert_not_contain 'You have to confirm your account before continuing'
assert_current_url "/"
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
user = User.to_adapter.find_first(order: [:id, :desc])
assert_equal 'new_user@test.com', user.email
refute user.confirmed?
assert_not user.confirmed?
end
test 'a guest user should receive the confirmation instructions from the default mailer' do
@@ -94,7 +94,7 @@ class RegistrationTest < Devise::IntegrationTest
click_button 'Sign up'
assert_current_url "/?custom=1"
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'a guest user cannot sign up with invalid information' do
@@ -112,11 +112,11 @@ class RegistrationTest < Devise::IntegrationTest
assert_template 'registrations/new'
assert_have_selector '#error_explanation'
assert_contain "Email is invalid"
assert_contain "Password confirmation doesn't match Password"
assert_contain %r{Password confirmation doesn[']t match Password}
assert_contain "2 errors prohibited"
assert_nil User.to_adapter.find_first
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'a guest should not sign up with email/password that already exists' do
@@ -135,7 +135,7 @@ class RegistrationTest < Devise::IntegrationTest
assert_current_url '/users'
assert_contain(/Email.*already.*taken/)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'a guest should not be able to change account' do
@@ -191,7 +191,7 @@ class RegistrationTest < Devise::IntegrationTest
assert_contain 'Your account has been updated successfully, but since your password was changed, you need to sign in again.'
assert_equal new_user_session_path, @request.path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -251,8 +251,8 @@ class RegistrationTest < Devise::IntegrationTest
fill_in 'current password', with: '12345678'
click_button 'Update'
assert_contain "Password confirmation doesn't match Password"
refute User.to_adapter.find_first.valid_password?('pas123')
assert_contain %r{Password confirmation doesn[']t match Password}
assert_not User.to_adapter.find_first.valid_password?('pas123')
end
test 'a signed in user should see a warning about minimum password length' do

View File

@@ -41,12 +41,12 @@ class RememberMeTest < Devise::IntegrationTest
test 'handle unverified requests gets rid of caches' do
swap ApplicationController, allow_forgery_protection: true do
post exhibit_user_url(1)
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
create_user_and_remember
post exhibit_user_url(1)
assert_equal "User is not authenticated", response.body
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end
@@ -59,8 +59,8 @@ class RememberMeTest < Devise::IntegrationTest
authenticity_token: "oops",
user: { email: "jose.valim@gmail.com", password: "123456", remember_me: "1" }
}
refute warden.authenticated?(:user)
refute request.cookies['remember_user_token']
assert_not warden.authenticated?(:user)
assert_not request.cookies['remember_user_token']
end
end
@@ -140,7 +140,7 @@ class RememberMeTest < Devise::IntegrationTest
get root_path
current_remember_token = request.cookies['remember_user_token']
refute_equal old_remember_token, current_remember_token
assert_not_equal old_remember_token, current_remember_token
end
end
@@ -166,13 +166,13 @@ class RememberMeTest < Devise::IntegrationTest
get root_path
assert_response :success
assert warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:admin)
end
test 'do not remember with invalid token' do
create_user_and_remember('add')
get users_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert_redirected_to new_user_session_path
end
@@ -180,7 +180,7 @@ class RememberMeTest < Devise::IntegrationTest
create_user_and_remember
swap Devise, remember_for: 0.days do
get users_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert_redirected_to new_user_session_path
end
end
@@ -191,11 +191,11 @@ class RememberMeTest < Devise::IntegrationTest
assert warden.authenticated?(:user)
delete destroy_user_session_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert_nil warden.cookies['remember_user_token']
get users_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'changing user password expires remember me token' do
@@ -205,7 +205,7 @@ class RememberMeTest < Devise::IntegrationTest
user.save!
get users_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test 'valid sign in calls after_remembered callback' do

View File

@@ -58,7 +58,7 @@ class SessionTimeoutTest < Devise::IntegrationTest
get users_path
assert_redirected_to users_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert warden.authenticated?(:admin)
end
end
@@ -72,8 +72,8 @@ class SessionTimeoutTest < Devise::IntegrationTest
assert_not_nil last_request_at
get root_path
refute warden.authenticated?(:user)
refute warden.authenticated?(:admin)
assert_not warden.authenticated?(:user)
assert_not warden.authenticated?(:admin)
end
end
@@ -109,8 +109,8 @@ class SessionTimeoutTest < Devise::IntegrationTest
follow_redirect!
assert_response :success
assert_contain 'Sign in'
refute warden.authenticated?(:user)
assert_contain 'Log in'
assert_not warden.authenticated?(:user)
end
test 'time out is not triggered on sign in' do
@@ -136,7 +136,7 @@ class SessionTimeoutTest < Devise::IntegrationTest
get expire_user_path(user)
get users_path
assert_redirected_to users_path
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
end

View File

@@ -6,7 +6,7 @@ class TrackableHooksTest < Devise::IntegrationTest
test "trackable should not run model validations" do
sign_in_as_user
refute User.validations_performed
assert_not User.validations_performed
end
test "current and last sign in timestamps are updated on each sign in" do

View File

@@ -117,7 +117,7 @@ class MappingTest < ActiveSupport::TestCase
assert mapping.authenticatable?
assert mapping.recoverable?
assert mapping.lockable?
refute mapping.omniauthable?
assert_not mapping.omniauthable?
end
test 'find mapping by path' do

View File

@@ -30,12 +30,12 @@ class AuthenticatableTest < ActiveSupport::TestCase
test 'find_or_initialize_with_errors adds blank error' do
user_with_error = User.find_or_initialize_with_errors([:email], { email: "" })
assert_equal ["Email can't be blank"], user_with_error.errors.full_messages_for(:email)
assert user_with_error.errors.added?(:email, :blank)
end
test 'find_or_initialize_with_errors adds invalid error' do
user_with_error = User.find_or_initialize_with_errors([:email], { email: "example@example.com" })
assert_equal ["Email is invalid"], user_with_error.errors.full_messages_for(:email)
assert user_with_error.errors.added?(:email, :invalid)
end
if defined?(ActionController::Parameters)
@@ -43,7 +43,7 @@ class AuthenticatableTest < ActiveSupport::TestCase
user = create_user(email: 'example@example.com')
attributes = ActionController::Parameters.new(email: 'example@example.com')
User.expects(:find_first_by_auth_conditions).with('email' => 'example@example.com').returns(user)
User.expects(:find_first_by_auth_conditions).with({ 'email' => 'example@example.com' }).returns(user)
User.find_or_initialize_with_errors([:email], attributes)
end
end

View File

@@ -28,7 +28,7 @@ class ConfirmableTest < ActiveSupport::TestCase
confirmation_tokens = []
3.times do
token = create_user.confirmation_token
refute_includes confirmation_tokens, token
assert_not_includes confirmation_tokens, token
confirmation_tokens << token
end
end
@@ -41,9 +41,9 @@ class ConfirmableTest < ActiveSupport::TestCase
end
test 'should verify whether a user is confirmed or not' do
refute new_user.confirmed?
assert_not new_user.confirmed?
user = create_user
refute user.confirmed?
assert_not user.confirmed?
user.confirm
assert user.confirmed?
end
@@ -53,7 +53,7 @@ class ConfirmableTest < ActiveSupport::TestCase
assert user.confirm
assert_blank user.errors[:email]
refute user.confirm
assert_not user.confirm
assert_equal "was already confirmed, please try signing in", user.errors[:email].join
end
@@ -67,14 +67,14 @@ class ConfirmableTest < ActiveSupport::TestCase
test 'should return a new record with errors when a invalid token is given' do
confirmed_user = User.confirm_by_token('invalid_confirmation_token')
refute confirmed_user.persisted?
assert_not confirmed_user.persisted?
assert_equal "is invalid", confirmed_user.errors[:confirmation_token].join
end
test 'should return a new record with errors when a blank token is given' do
confirmed_user = User.confirm_by_token('')
refute confirmed_user.persisted?
assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
assert_not confirmed_user.persisted?
assert confirmed_user.errors.added?(:confirmation_token, :blank)
end
test 'should return a new record with errors when a blank token is given and a record exists on the database' do
@@ -82,8 +82,8 @@ class ConfirmableTest < ActiveSupport::TestCase
confirmed_user = User.confirm_by_token('')
refute user.reload.confirmed?
assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
assert_not user.reload.confirmed?
assert confirmed_user.errors.added?(:confirmation_token, :blank)
end
test 'should return a new record with errors when a nil token is given and a record exists on the database' do
@@ -91,8 +91,8 @@ class ConfirmableTest < ActiveSupport::TestCase
confirmed_user = User.confirm_by_token(nil)
refute user.reload.confirmed?
assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
assert_not user.reload.confirmed?
assert confirmed_user.errors.added?(:confirmation_token, :blank)
end
test 'should generate errors for a user email if user is already confirmed' do
@@ -145,7 +145,7 @@ class ConfirmableTest < ActiveSupport::TestCase
assert_email_not_sent do
user.save!
refute user.confirmed?
assert_not user.confirmed?
end
end
@@ -165,7 +165,7 @@ class ConfirmableTest < ActiveSupport::TestCase
test 'should return a new user if no email was found' do
confirmation_user = User.send_confirmation_instructions(email: "invalid@example.com")
refute confirmation_user.persisted?
assert_not confirmation_user.persisted?
end
test 'should add error to new user email if no email was found' do
@@ -212,7 +212,7 @@ class ConfirmableTest < ActiveSupport::TestCase
test 'should not be able to send instructions if the user is already confirmed' do
user = create_user
user.confirm
refute user.resend_confirmation_instructions
assert_not user.resend_confirmation_instructions
assert user.confirmed?
assert_equal 'was already confirmed, please try signing in', user.errors[:email].join
end
@@ -221,7 +221,7 @@ class ConfirmableTest < ActiveSupport::TestCase
swap Devise, allow_unconfirmed_access_for: 1.day do
user = create_user
user.confirmation_sent_at = 2.days.ago
refute user.active_for_authentication?
assert_not user.active_for_authentication?
Devise.allow_unconfirmed_access_for = 3.days
assert user.active_for_authentication?
@@ -237,14 +237,14 @@ class ConfirmableTest < ActiveSupport::TestCase
assert user.active_for_authentication?
user.confirmation_sent_at = 5.days.ago
refute user.active_for_authentication?
assert_not user.active_for_authentication?
end
end
test 'should be active when already confirmed' do
user = create_user
refute user.confirmed?
refute user.active_for_authentication?
assert_not user.confirmed?
assert_not user.active_for_authentication?
user.confirm
assert user.confirmed?
@@ -255,7 +255,7 @@ class ConfirmableTest < ActiveSupport::TestCase
Devise.allow_unconfirmed_access_for = 0.days
user = create_user
user.confirmation_sent_at = Time.zone.today
refute user.active_for_authentication?
assert_not user.active_for_authentication?
end
test 'should not be active when confirm period is set to 0 days' do
@@ -264,7 +264,7 @@ class ConfirmableTest < ActiveSupport::TestCase
Timecop.freeze(Time.zone.today) do
user.confirmation_sent_at = Time.zone.today
refute user.active_for_authentication?
assert_not user.active_for_authentication?
end
end
@@ -280,7 +280,7 @@ class ConfirmableTest < ActiveSupport::TestCase
user = create_user
user.confirmation_sent_at = nil
user.save
refute user.reload.active_for_authentication?
assert_not user.reload.active_for_authentication?
end
test 'should be active without confirmation when confirmation is not required' do
@@ -313,8 +313,8 @@ class ConfirmableTest < ActiveSupport::TestCase
swap Devise, confirmation_keys: [:username, :email] do
user = create_user
confirm_user = User.send_confirmation_instructions(email: user.email)
refute confirm_user.persisted?
assert_equal "can't be blank", confirm_user.errors[:username].join
assert_not confirm_user.persisted?
assert confirm_user.errors.added?(:username, :blank)
end
end
@@ -338,7 +338,7 @@ class ConfirmableTest < ActiveSupport::TestCase
test 'should not accept confirmation email token after 4 days when expiration is set to 3 days' do
swap Devise, confirm_within: 3.days do
refute confirm_user_by_token_with_confirmation_sent_at(4.days.ago)
assert_not confirm_user_by_token_with_confirmation_sent_at(4.days.ago)
end
end
@@ -378,14 +378,14 @@ class ConfirmableTest < ActiveSupport::TestCase
self.username = self.username.to_s + 'updated'
end
old = user.username
refute user.confirm
assert_not user.confirm
assert_equal user.username, old
end
test 'should always perform validations upon confirm when ensure valid true' do
admin = create_admin
admin.stubs(:valid?).returns(false)
refute admin.confirm(ensure_valid: true)
assert_not admin.confirm(ensure_valid: true)
end
end
@@ -411,7 +411,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
admin.skip_reconfirmation!
assert admin.update(email: 'new_test@example.com')
assert admin.confirmed?
refute admin.pending_reconfirmation?
assert_not admin.pending_reconfirmation?
assert_equal original_token, admin.confirmation_token
end
@@ -502,7 +502,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
test 'should return a new admin if no email or unconfirmed_email was found' do
confirmation_admin = Admin.send_confirmation_instructions(email: "invalid@email.com")
refute confirmation_admin.persisted?
assert_not confirmation_admin.persisted?
end
test 'should add error to new admin email if no email or unconfirmed_email was found' do
@@ -538,7 +538,7 @@ class ReconfirmableTest < ActiveSupport::TestCase
test 'should not require reconfirmation after creating a record' do
admin = create_admin
assert !admin.pending_reconfirmation?
assert_not admin.pending_reconfirmation?
end
test 'should not require reconfirmation after creating a record with #save called in callback' do
@@ -547,12 +547,12 @@ class ReconfirmableTest < ActiveSupport::TestCase
end
admin = Admin::WithSaveInCallback.create(valid_attributes.except(:username))
assert !admin.pending_reconfirmation?
assert_not admin.pending_reconfirmation?
end
test 'should require reconfirmation after creating a record and updating the email' do
admin = create_admin
assert !admin.instance_variable_get(:@bypass_confirmation_postpone)
assert_not admin.instance_variable_get(:@bypass_confirmation_postpone)
admin.email = "new_test@email.com"
admin.save
assert admin.pending_reconfirmation?

View File

@@ -133,7 +133,7 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'should test for a valid password' do
user = create_user
assert user.valid_password?('12345678')
refute user.valid_password?('654321')
assert_not user.valid_password?('654321')
end
test 'should not raise error with an empty password' do
@@ -145,7 +145,7 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'should be an invalid password if the user has an empty password' do
user = create_user
user.encrypted_password = ''
refute user.valid_password?('654321')
assert_not user.valid_password?('654321')
end
test 'should respond to current password' do
@@ -161,7 +161,7 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'should add an error to current password when it is invalid' do
user = create_user
refute user.update_with_password(current_password: 'other',
assert_not user.update_with_password(current_password: 'other',
password: 'pass4321', password_confirmation: 'pass4321')
assert user.reload.valid_password?('12345678')
assert_match "is invalid", user.errors[:current_password].join
@@ -169,19 +169,19 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'should add an error to current password when it is blank' do
user = create_user
refute user.update_with_password(password: 'pass4321',
assert_not user.update_with_password(password: 'pass4321',
password_confirmation: 'pass4321')
assert user.reload.valid_password?('12345678')
assert_match "can't be blank", user.errors[:current_password].join
assert user.errors.added?(:current_password, :blank)
end
test 'should run validations even when current password is invalid or blank' do
user = UserWithValidation.create!(valid_attributes)
user.save
assert user.persisted?
refute user.update_with_password(username: "")
assert_not user.update_with_password(username: "")
assert_match "usertest", user.reload.username
assert_match "can't be blank", user.errors[:username].join
assert user.errors.added?(:username, :blank)
end
test 'should ignore password and its confirmation if they are blank' do
@@ -192,14 +192,14 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'should not update password with invalid confirmation' do
user = create_user
refute user.update_with_password(current_password: '12345678',
assert_not user.update_with_password(current_password: '12345678',
password: 'pass4321', password_confirmation: 'other')
assert user.reload.valid_password?('12345678')
end
test 'should clean up password fields on failure' do
user = create_user
refute user.update_with_password(current_password: '12345678',
assert_not user.update_with_password(current_password: '12345678',
password: 'pass4321', password_confirmation: 'other')
assert user.password.blank?
assert user.password_confirmation.blank?
@@ -214,28 +214,28 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'should not update password without password' do
user = create_user
user.update_without_password(password: 'pass4321', password_confirmation: 'pass4321')
assert !user.reload.valid_password?('pass4321')
assert_not user.reload.valid_password?('pass4321')
assert user.valid_password?('12345678')
end
test 'should destroy user if current password is valid' do
user = create_user
assert user.destroy_with_password('12345678')
assert !user.persisted?
assert_not user.persisted?
end
test 'should not destroy user with invalid password' do
user = create_user
refute user.destroy_with_password('other')
assert_not user.destroy_with_password('other')
assert user.persisted?
assert_match "is invalid", user.errors[:current_password].join
end
test 'should not destroy user with blank password' do
user = create_user
refute user.destroy_with_password(nil)
assert_not user.destroy_with_password(nil)
assert user.persisted?
assert_match "can't be blank", user.errors[:current_password].join
assert user.errors.added?(:current_password, :blank)
end
test 'should not email on password change' do
@@ -289,7 +289,7 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
test 'downcase_keys with validation' do
User.create(email: "HEllO@example.com", password: "123456")
user = User.create(email: "HEllO@example.com", password: "123456")
assert !user.valid?
assert_not user.valid?
end
test 'required_fields should be encryptable_password and the email field by default' do

View File

@@ -34,7 +34,7 @@ class LockableTest < ActiveSupport::TestCase
user.confirm
swap Devise, lock_strategy: :none, maximum_attempts: 2 do
3.times { user.valid_for_authentication?{ false } }
assert !user.access_locked?
assert_not user.access_locked?
assert_equal 0, user.failed_attempts
end
end
@@ -72,8 +72,8 @@ class LockableTest < ActiveSupport::TestCase
test "reset_failed_attempts! does not try to reset if not using failed attempts strategy" do
admin = create_admin
refute_respond_to admin, :failed_attempts
refute admin.reset_failed_attempts!
assert_not_respond_to admin, :failed_attempts
assert_not admin.reset_failed_attempts!
end
test 'should be valid for authentication with a unlocked user' do
@@ -85,7 +85,7 @@ class LockableTest < ActiveSupport::TestCase
test "should verify whether a user is locked or not" do
user = create_user
refute user.access_locked?
assert_not user.access_locked?
user.lock_access!
assert user.access_locked?
end
@@ -95,7 +95,7 @@ class LockableTest < ActiveSupport::TestCase
user.confirm
assert user.active_for_authentication?
user.lock_access!
refute user.active_for_authentication?
assert_not user.active_for_authentication?
end
test "should unlock a user by cleaning locked_at, failed_attempts and unlock_token" do
@@ -111,7 +111,7 @@ class LockableTest < ActiveSupport::TestCase
end
test "new user should not be locked and should have zero failed_attempts" do
refute new_user.access_locked?
assert_not new_user.access_locked?
assert_equal 0, create_user.failed_attempts
end
@@ -122,7 +122,7 @@ class LockableTest < ActiveSupport::TestCase
assert user.access_locked?
Devise.unlock_in = 1.hour
refute user.access_locked?
assert_not user.access_locked?
end
end
@@ -147,7 +147,7 @@ class LockableTest < ActiveSupport::TestCase
user = create_user
user.lock_access!
token = user.unlock_token
refute_includes unlock_tokens, token
assert_not_includes unlock_tokens, token
unlock_tokens << token
end
end
@@ -201,19 +201,19 @@ class LockableTest < ActiveSupport::TestCase
raw = user.send_unlock_instructions
locked_user = User.unlock_access_by_token(raw)
assert_equal user, locked_user
refute user.reload.access_locked?
assert_not user.reload.access_locked?
end
test 'should return a new record with errors when a invalid token is given' do
locked_user = User.unlock_access_by_token('invalid_token')
refute locked_user.persisted?
assert_not locked_user.persisted?
assert_equal "is invalid", locked_user.errors[:unlock_token].join
end
test 'should return a new record with errors when a blank token is given' do
locked_user = User.unlock_access_by_token('')
refute locked_user.persisted?
assert_equal "can't be blank", locked_user.errors[:unlock_token].join
assert_not locked_user.persisted?
assert locked_user.errors.added?(:unlock_token, :blank)
end
test 'should find a user to send unlock instructions' do
@@ -225,7 +225,7 @@ class LockableTest < ActiveSupport::TestCase
test 'should return a new user if no email was found' do
unlock_user = User.send_unlock_instructions(email: "invalid@example.com")
refute unlock_user.persisted?
assert_not unlock_user.persisted?
end
test 'should add error to new user email if no email was found' do
@@ -245,23 +245,23 @@ class LockableTest < ActiveSupport::TestCase
swap Devise, unlock_keys: [:username, :email] do
user = create_user
unlock_user = User.send_unlock_instructions(email: user.email)
refute unlock_user.persisted?
assert_equal "can't be blank", unlock_user.errors[:username].join
assert_not unlock_user.persisted?
assert unlock_user.errors.added?(:username, :blank)
end
end
test 'should not be able to send instructions if the user is not locked' do
user = create_user
refute user.resend_unlock_instructions
refute user.access_locked?
assert_not user.resend_unlock_instructions
assert_not user.access_locked?
assert_equal 'was not locked', user.errors[:email].join
end
test 'should not be able to send instructions if the user if not locked and have username as unlock key' do
swap Devise, unlock_keys: [:username] do
user = create_user
refute user.resend_unlock_instructions
refute user.access_locked?
assert_not user.resend_unlock_instructions
assert_not user.access_locked?
assert_equal 'was not locked', user.errors[:username].join
end
end

View File

@@ -18,7 +18,7 @@ class RecoverableTest < ActiveSupport::TestCase
user = create_user
user.send_reset_password_instructions
token = user.reset_password_token
refute_includes reset_password_tokens, token
assert_not_includes reset_password_tokens, token
reset_password_tokens << token
end
end
@@ -94,14 +94,14 @@ class RecoverableTest < ActiveSupport::TestCase
user = create_user
user.send_reset_password_instructions
assert_present user.reset_password_token
refute user.reset_password('123456789', '987654321')
assert_not user.reset_password('123456789', '987654321')
assert_present user.reset_password_token
end
test 'should not reset password with invalid data' do
user = create_user
user.stubs(:valid?).returns(false)
refute user.reset_password('123456789', '987654321')
assert_not user.reset_password('123456789', '987654321')
end
test 'should reset reset password token and send instructions by email' do
@@ -121,7 +121,7 @@ class RecoverableTest < ActiveSupport::TestCase
test 'should return a new record with errors if user was not found by e-mail' do
reset_password_user = User.send_reset_password_instructions(email: "invalid@example.com")
refute reset_password_user.persisted?
assert_not reset_password_user.persisted?
assert_equal "not found", reset_password_user.errors[:email].join
end
@@ -134,12 +134,12 @@ class RecoverableTest < ActiveSupport::TestCase
end
test 'should require all reset_password_keys' do
swap Devise, reset_password_keys: [:username, :email] do
user = create_user
reset_password_user = User.send_reset_password_instructions(email: user.email)
refute reset_password_user.persisted?
assert_equal "can't be blank", reset_password_user.errors[:username].join
end
swap Devise, reset_password_keys: [:username, :email] do
user = create_user
reset_password_user = User.send_reset_password_instructions(email: user.email)
assert_not reset_password_user.persisted?
assert reset_password_user.errors.added?(:username, :blank)
end
end
test 'should reset reset_password_token before send the reset instructions email' do
@@ -166,14 +166,14 @@ class RecoverableTest < ActiveSupport::TestCase
test 'should return a new record with errors if no reset_password_token is found' do
reset_password_user = User.reset_password_by_token(reset_password_token: 'invalid_token')
refute reset_password_user.persisted?
assert_not reset_password_user.persisted?
assert_equal "is invalid", reset_password_user.errors[:reset_password_token].join
end
test 'should return a new record with errors if reset_password_token is blank' do
reset_password_user = User.reset_password_by_token(reset_password_token: '')
refute reset_password_user.persisted?
assert_match "can't be blank", reset_password_user.errors[:reset_password_token].join
assert_not reset_password_user.persisted?
assert reset_password_user.errors.added?(:reset_password_token, :blank)
end
test 'should return a new record with errors if password is blank' do
@@ -181,8 +181,8 @@ class RecoverableTest < ActiveSupport::TestCase
raw = user.send_reset_password_instructions
reset_password_user = User.reset_password_by_token(reset_password_token: raw, password: '')
refute reset_password_user.errors.empty?
assert_match "can't be blank", reset_password_user.errors[:password].join
assert_not reset_password_user.errors.empty?
assert reset_password_user.errors.added?(:password, :blank)
assert_equal raw, reset_password_user.reset_password_token
end
@@ -191,8 +191,8 @@ class RecoverableTest < ActiveSupport::TestCase
raw = user.send_reset_password_instructions
reset_password_user = User.reset_password_by_token(reset_password_token: raw)
refute reset_password_user.errors.empty?
assert_match "can't be blank", reset_password_user.errors[:password].join
assert_not reset_password_user.errors.empty?
assert reset_password_user.errors.added?(:password, :blank)
assert_equal raw, reset_password_user.reset_password_token
end
@@ -209,7 +209,7 @@ class RecoverableTest < ActiveSupport::TestCase
assert_nil reset_password_user.reset_password_token
user.reload
refute user.valid_password?(old_password)
assert_not user.valid_password?(old_password)
assert user.valid_password?('new_password')
assert_nil user.reset_password_token
end
@@ -231,7 +231,7 @@ class RecoverableTest < ActiveSupport::TestCase
user.reload
assert user.valid_password?(old_password)
refute user.valid_password?('new_password')
assert_not user.valid_password?('new_password')
assert_equal "has expired, please request a new one", reset_password_user.errors[:reset_password_token].join
end
end

View File

@@ -32,7 +32,9 @@ class SerializableTest < ActiveSupport::TestCase
end
test 'constant `BLACKLIST_FOR_SERIALIZATION` is deprecated' do
assert_deprecated { Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION }
assert_deprecated("Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION", Devise.deprecator) do
Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION
end
end
def assert_key(key, subject)
@@ -40,7 +42,7 @@ class SerializableTest < ActiveSupport::TestCase
end
def assert_no_key(key, subject)
assert !subject.key?(key), "Expected #{subject.inspect} to not have key #{key.inspect}"
assert_not subject.key?(key), "Expected #{subject.inspect} to not have key #{key.inspect}"
end
def from_json(options = nil)

View File

@@ -9,11 +9,11 @@ class TimeoutableTest < ActiveSupport::TestCase
end
test 'should not be expired' do
refute new_user.timedout?(29.minutes.ago)
assert_not new_user.timedout?(29.minutes.ago)
end
test 'should not be expired when params is nil' do
refute new_user.timedout?(nil)
assert_not new_user.timedout?(nil)
end
test 'should use timeout_in method' do
@@ -21,23 +21,23 @@ class TimeoutableTest < ActiveSupport::TestCase
user.instance_eval { def timeout_in; 10.minutes end }
assert user.timedout?(12.minutes.ago)
refute user.timedout?(8.minutes.ago)
assert_not user.timedout?(8.minutes.ago)
end
test 'should not be expired when timeout_in method returns nil' do
user = new_user
user.instance_eval { def timeout_in; nil end }
refute user.timedout?(10.hours.ago)
assert_not user.timedout?(10.hours.ago)
end
test 'fallback to Devise config option' do
swap Devise, timeout_in: 1.minute do
user = new_user
assert user.timedout?(2.minutes.ago)
refute user.timedout?(30.seconds.ago)
assert_not user.timedout?(30.seconds.ago)
Devise.timeout_in = 5.minutes
refute user.timedout?(2.minutes.ago)
assert_not user.timedout?(2.minutes.ago)
assert user.timedout?(6.minutes.ago)
end
end

View File

@@ -8,7 +8,7 @@ class ValidatableTest < ActiveSupport::TestCase
user = new_user(email: nil)
assert user.invalid?
assert user.errors[:email]
assert_equal 'can\'t be blank', user.errors[:email].join
assert user.errors.added?(:email, :blank)
end
test 'should require uniqueness of email if email has changed, allowing blank' do
@@ -52,14 +52,14 @@ class ValidatableTest < ActiveSupport::TestCase
test 'should require password to be set when creating a new record' do
user = new_user(password: '', password_confirmation: '')
assert user.invalid?
assert_equal 'can\'t be blank', user.errors[:password].join
assert user.errors.added?(:password, :blank)
end
test 'should require confirmation to be set when creating a new record' do
user = new_user(password: 'new_password', password_confirmation: 'blabla')
assert user.invalid?
assert_equal 'doesn\'t match Password', user.errors[:password_confirmation].join
assert user.errors.added?(:password_confirmation, :confirmation, attribute: "Password")
end
test 'should require password when updating/resetting password' do
@@ -69,7 +69,7 @@ class ValidatableTest < ActiveSupport::TestCase
user.password_confirmation = ''
assert user.invalid?
assert_equal 'can\'t be blank', user.errors[:password].join
assert user.errors.added?(:password, :blank)
end
test 'should require confirmation when updating/resetting password' do
@@ -77,7 +77,7 @@ class ValidatableTest < ActiveSupport::TestCase
user.password_confirmation = 'another_password'
assert user.invalid?
assert_equal 'doesn\'t match Password', user.errors[:password_confirmation].join
assert user.errors.added?(:password_confirmation, :confirmation, attribute: "Password")
end
test 'should require a password with minimum of 7 characters' do
@@ -99,7 +99,7 @@ class ValidatableTest < ActiveSupport::TestCase
user.password_confirmation = 'confirmation'
assert user.invalid?
refute (user.errors[:password].join =~ /is too long/)
assert_not (user.errors[:password].join =~ /is too long/)
end
test 'should complain about length even if password is not required' do
@@ -110,9 +110,12 @@ class ValidatableTest < ActiveSupport::TestCase
end
test 'should not be included in objects with invalid API' do
assert_raise RuntimeError do
exception = assert_raise RuntimeError do
Class.new.send :include, Devise::Models::Validatable
end
expected_message = /Could not use :validatable module since .* does not respond to the following methods: validates_presence_of.*/
assert_match expected_message, exception.message
end
test 'required_fields should be an empty array' do

View File

@@ -15,7 +15,7 @@ class ActiveRecordTest < ActiveSupport::TestCase
end
(Devise::ALL - modules).each do |mod|
refute include_module?(klass, mod)
assert_not include_module?(klass, mod)
end
end

View File

@@ -5,7 +5,9 @@ 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.rails6_and_up?
if Devise::Test.rails71_and_up?
ActiveRecord::MigrationContext.new(migrate_path).migrate
elsif Devise::Test.rails6_and_up?
ActiveRecord::MigrationContext.new(migrate_path, ActiveRecord::SchemaMigration).migrate
elsif Devise::Test.rails52_and_up?
ActiveRecord::MigrationContext.new(migrate_path).migrate

View File

@@ -1,8 +1,15 @@
# frozen_string_literal: true
class AdminsController < ApplicationController
around_action :set_locale
before_action :authenticate_admin!
def index
end
private
def set_locale
I18n.with_locale(params[:locale] || I18n.default_locale) { yield }
end
end

View File

@@ -50,8 +50,12 @@ module RailsApp
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
end
if Devise::Test.rails7_and_up?
if Devise::Test.rails70?
config.active_record.legacy_connection_handling = false
end
if Devise::Test.rails70_and_up?
config.active_support.cache_format_version = 7.0
end
end
end

View File

@@ -8,10 +8,18 @@ module Devise
module Test
# Detection for minor differences between Rails versions in tests.
def self.rails7_and_up?
def self.rails71_and_up?
!rails70? && Rails::VERSION::MAJOR >= 7
end
def self.rails70_and_up?
Rails::VERSION::MAJOR >= 7
end
def self.rails70?
Rails.version.start_with? '7.0'
end
def self.rails6_and_up?
Rails::VERSION::MAJOR >= 6
end

View File

@@ -32,7 +32,11 @@ RailsApp::Application.configure do
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
if Devise::Test.rails71_and_up?
config.action_dispatch.show_exceptions = :none
else
config.action_dispatch.show_exceptions = false
end
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false

View File

@@ -10,11 +10,7 @@ module SharedAdmin
allow_unconfirmed_access_for: 2.weeks, reconfirmable: true
validates_length_of :reset_password_token, minimum: 3, allow_blank: true
if Devise::Test.rails51?
validates_uniqueness_of :email, allow_blank: true, if: :will_save_change_to_email?
else
validates_uniqueness_of :email, allow_blank: true, if: :email_changed?
end
validates_uniqueness_of :email, allow_blank: true, if: :devise_will_save_change_to_email?
end
def raw_confirmation_token

View File

@@ -8,4 +8,10 @@ class RailsTest < ActiveSupport::TestCase
assert_equal :load_config_initializers, initializer.after
assert_equal :build_middleware_stack, initializer.before
end
if Devise::Test.rails71_and_up?
test 'deprecator is added to application deprecators' do
assert_not_nil Rails.application.deprecators[:devise]
end
end
end

View File

@@ -2,7 +2,7 @@
require 'test_helper'
ExpectedRoutingError = MiniTest::Assertion
ExpectedRoutingError = Minitest::Assertion
class DefaultRoutingTest < ActionController::TestCase
test 'map new user session' do

View File

@@ -3,8 +3,6 @@
require 'active_support/test_case'
class ActiveSupport::TestCase
VALID_AUTHENTICATION_TOKEN = 'AbCdEfGhIjKlMnOpQrSt'.freeze
def setup_mailer
ActionMailer::Base.deliveries = []
end
@@ -73,6 +71,17 @@ class ActiveSupport::TestCase
end
end
def swap_model_config(model, new_values)
new_values.each do |key, value|
model.send :"#{key}=", value
end
yield
ensure
new_values.each_key do |key|
model.remove_instance_variable :"@#{key}"
end
end
def clear_cached_variables(options)
if options.key?(:case_insensitive_keys) || options.key?(:strip_whitespace_keys)
Devise.mappings.each do |_, mapping|

View File

@@ -61,8 +61,8 @@ class ActionDispatch::IntegrationTest
# account Middleware redirects.
#
def assert_redirected_to(url)
assert_includes [301, 302], @integration_session.status,
"Expected status to be 301 or 302, got #{@integration_session.status}"
assert_includes [301, 302, 303], @integration_session.status,
"Expected status to be 301, 302, or 303, got #{@integration_session.status}"
assert_url url, @integration_session.headers["Location"]
end

View File

@@ -0,0 +1,5 @@
pt-BR:
devise:
failure:
invalid: "%{authentication_keys} ou senha inválidos."
unauthenticated: "Para continuar, faça login ou registre-se."

View File

@@ -0,0 +1,12 @@
# Monkey patch for Nokogiri changes - https://github.com/sparklemotion/nokogiri/issues/2469
module Webrat
module Matchers
class HaveSelector
def query
Nokogiri::CSS.parse(@expected.to_s).map do |ast|
ast.to_xpath("//", Nokogiri::CSS::XPathVisitor.new)
end.first
end
end
end
end

View File

@@ -15,7 +15,7 @@ class TestControllerHelpersTest < Devise::ControllerTestCase
test "redirects if attempting to access a page with an unconfirmed account" do
swap Devise, allow_unconfirmed_access_for: 0.days do
user = create_user
assert !user.active_for_authentication?
assert_not user.active_for_authentication?
sign_in user
get :index
@@ -26,7 +26,7 @@ class TestControllerHelpersTest < Devise::ControllerTestCase
test "returns nil if accessing current_user with an unconfirmed account" do
swap Devise, allow_unconfirmed_access_for: 0.days do
user = create_user
assert !user.active_for_authentication?
assert_not user.active_for_authentication?
sign_in user
get :accept, params: { id: user }
@@ -97,7 +97,12 @@ class TestControllerHelpersTest < Devise::ControllerTestCase
test "returns the body of a failure app" do
get :index
assert_equal "<html><body>You are being <a href=\"http://test.host/users/sign_in\">redirected</a>.</body></html>", response.body
if Devise::Test.rails71_and_up?
assert_empty response.body
else
assert_equal "<html><body>You are being <a href=\"http://test.host/users/sign_in\">redirected</a>.</body></html>", response.body
end
end
test "returns the content type of a failure app" do
@@ -203,6 +208,11 @@ class TestControllerHelpersForStreamingControllerTest < Devise::ControllerTestCa
test "doesn't hang when sending an authentication error response body" do
get :index
assert_equal "<html><body>You are being <a href=\"http://test.host/users/sign_in\">redirected</a>.</body></html>", response.body
if Devise::Test.rails71_and_up?
assert_empty response.body
else
assert_equal "<html><body>You are being <a href=\"http://test.host/users/sign_in\">redirected</a>.</body></html>", response.body
end
end
end

View File

@@ -18,7 +18,7 @@ class TestIntegrationsHelpersTest < Devise::IntegrationTest
sign_out user
visit '/'
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
end
test '#sign_out does not signs out other scopes' do
@@ -28,7 +28,7 @@ class TestIntegrationsHelpersTest < Devise::IntegrationTest
visit '/'
refute warden.authenticated?(:user)
assert_not warden.authenticated?(:user)
assert warden.authenticated?(:admin)
end
end

View File

@@ -10,7 +10,7 @@ require "rails_app/config/environment"
require "rails/test_help"
require "orm/#{DEVISE_ORM}"
I18n.load_path << File.expand_path("../support/locale/en.yml", __FILE__)
I18n.load_path.concat Dir["#{File.dirname(__FILE__)}/support/locale/*.yml"]
require 'mocha/minitest'
require 'timecop'
@@ -23,6 +23,22 @@ end
if ActiveSupport.respond_to?(:test_order)
ActiveSupport.test_order = :random
end
class ActiveSupport::TestCase
if ActiveSupport.version < Gem::Version.new("5.0")
def assert_deprecated(match, deprecator)
super(match) do
# TODO: remove extra begin..end when dropping support for Ruby <= 2.4
begin
behavior = deprecator.behavior
deprecator.behavior = ActiveSupport::Deprecation.behavior
yield
ensure
deprecator.behavior = behavior
end
end
end
end
end
OmniAuth.config.logger = Logger.new('/dev/null')