about summary refs log tree commit diff
path: root/app
AgeCommit message (Collapse)Author
2020-05-13New Crowdin translations (#13398)Eugen Rochko
* New translations simple_form.en.yml (French) [ci skip] * New translations en.json (Portuguese, Brazilian) [ci skip] * New translations en.json (Portuguese, Brazilian) [ci skip] * New translations en.yml (Japanese) [ci skip] * New translations en.yml (Korean) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations en.json (Korean) [ci skip] * New translations en.yml (Persian) [ci skip] * New translations en.yml (French) [ci skip] * New translations en.yml (Catalan) [ci skip] * New translations en.yml (Spanish, Argentina) [ci skip] * New translations en.yml (Spanish) [ci skip] * New translations en.yml (Galician) [ci skip] * New translations en.yml (Greek) [ci skip] * New translations en.yml (Spanish, Argentina) [ci skip] * New translations en.yml (Portuguese) [ci skip] * New translations en.yml (Portuguese, Brazilian) [ci skip] * New translations en.yml (Portuguese, Brazilian) [ci skip] * New translations en.yml (Portuguese, Brazilian) [ci skip] * New translations en.yml (Icelandic) [ci skip] * New translations en.yml (Corsican) [ci skip] * New translations en.yml (Indonesian) [ci skip] * New translations en.yml (Italian) [ci skip] * New translations en.yml (Polish) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations doorkeeper.en.yml (Albanian) [ci skip] * New translations activerecord.en.yml (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations doorkeeper.en.yml (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.yml (Asturian) [ci skip] * New translations en.yml (Welsh) [ci skip] * New translations en.yml (Welsh) [ci skip] * New translations en.json (Welsh) [ci skip] * New translations simple_form.en.yml (Welsh) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.yml (Albanian) [ci skip] * New translations devise.en.yml (Albanian) [ci skip] * New translations simple_form.en.yml (Albanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations en.yml (Slovak) [ci skip] * New translations en.yml (French) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations en.json (Armenian) [ci skip] * New translations en.yml (Turkish) [ci skip] * New translations simple_form.en.yml (Turkish) [ci skip] * New translations en.json (Indonesian) [ci skip] * New translations en.yml (Catalan) [ci skip] * New translations en.yml (Thai) [ci skip] * New translations simple_form.en.yml (Danish) [ci skip] * New translations en.json (Danish) [ci skip] * New translations en.yml (Danish) [ci skip] * New translations en.json (Armenian) [ci skip] * New translations activerecord.en.yml (Chinese Simplified) [ci skip] * New translations devise.en.yml (Persian) [ci skip] * New translations activerecord.en.yml (Persian) [ci skip] * New translations devise.en.yml (Indonesian) [ci skip] * New translations activerecord.en.yml (Indonesian) [ci skip] * New translations devise.en.yml (Chinese Traditional) [ci skip] * New translations activerecord.en.yml (Chinese Traditional) [ci skip] * New translations devise.en.yml (Chinese Simplified) [ci skip] * New translations devise.en.yml (Ukrainian) [ci skip] * New translations devise.en.yml (Tamil) [ci skip] * New translations activerecord.en.yml (Ukrainian) [ci skip] * New translations devise.en.yml (Turkish) [ci skip] * New translations activerecord.en.yml (Turkish) [ci skip] * New translations devise.en.yml (Swedish) [ci skip] * New translations activerecord.en.yml (Swedish) [ci skip] * New translations devise.en.yml (Serbian (Cyrillic)) [ci skip] * New translations activerecord.en.yml (Serbian (Cyrillic)) [ci skip] * New translations activerecord.en.yml (Tamil) [ci skip] * New translations activerecord.en.yml (Spanish, Argentina) [ci skip] * New translations activerecord.en.yml (Slovenian) [ci skip] * New translations activerecord.en.yml (Corsican) [ci skip] * New translations devise.en.yml (Occitan) [ci skip] * New translations devise.en.yml (Esperanto) [ci skip] * New translations activerecord.en.yml (Esperanto) [ci skip] * New translations en.json (Esperanto) [ci skip] * New translations devise.en.yml (Welsh) [ci skip] * New translations activerecord.en.yml (Welsh) [ci skip] * New translations devise.en.yml (Spanish, Argentina) [ci skip] * New translations devise.en.yml (Estonian) [ci skip] * New translations activerecord.en.yml (Estonian) [ci skip] * New translations devise.en.yml (Kazakh) [ci skip] * New translations activerecord.en.yml (Kazakh) [ci skip] * New translations devise.en.yml (Thai) [ci skip] * New translations activerecord.en.yml (Thai) [ci skip] * New translations devise.en.yml (Bengali) [ci skip] * New translations activerecord.en.yml (Bengali) [ci skip] * New translations devise.en.yml (Slovenian) [ci skip] * New translations activerecord.en.yml (Slovak) [ci skip] * New translations devise.en.yml (Czech) [ci skip] * New translations activerecord.en.yml (Greek) [ci skip] * New translations activerecord.en.yml (German) [ci skip] * New translations doorkeeper.en.yml (Danish) [ci skip] * New translations devise.en.yml (Danish) [ci skip] * New translations activerecord.en.yml (Danish) [ci skip] * New translations en.yml (Danish) [ci skip] * New translations en.json (Danish) [ci skip] * New translations activerecord.en.yml (Czech) [ci skip] * New translations activerecord.en.yml (Basque) [ci skip] * New translations devise.en.yml (Catalan) [ci skip] * New translations activerecord.en.yml (Catalan) [ci skip] * New translations devise.en.yml (Arabic) [ci skip] * New translations activerecord.en.yml (Arabic) [ci skip] * New translations devise.en.yml (Spanish) [ci skip] * New translations activerecord.en.yml (Spanish) [ci skip] * New translations activerecord.en.yml (French) [ci skip] * New translations devise.en.yml (Greek) [ci skip] * New translations devise.en.yml (Basque) [ci skip] * New translations en.yml (Slovak) [ci skip] * New translations activerecord.en.yml (Dutch) [ci skip] * New translations activerecord.en.yml (Russian) [ci skip] * New translations activerecord.en.yml (Portuguese) [ci skip] * New translations devise.en.yml (Polish) [ci skip] * New translations activerecord.en.yml (Polish) [ci skip] * New translations devise.en.yml (Norwegian) [ci skip] * New translations activerecord.en.yml (Norwegian) [ci skip] * New translations devise.en.yml (Dutch) [ci skip] * New translations devise.en.yml (Korean) [ci skip] * New translations activerecord.en.yml (Finnish) [ci skip] * New translations activerecord.en.yml (Korean) [ci skip] * New translations devise.en.yml (Japanese) [ci skip] * New translations activerecord.en.yml (Japanese) [ci skip] * New translations devise.en.yml (Italian) [ci skip] * New translations activerecord.en.yml (Italian) [ci skip] * New translations devise.en.yml (Armenian) [ci skip] * New translations activerecord.en.yml (Armenian) [ci skip] * New translations devise.en.yml (Finnish) [ci skip] * New translations devise.en.yml (Corsican) [ci skip] * New translations en.json (Esperanto) [ci skip] * New translations devise.en.yml (Esperanto) [ci skip] * New translations simple_form.en.yml (Czech) [ci skip] * New translations en.yml (Norwegian) [ci skip] * New translations simple_form.en.yml (Norwegian) [ci skip] * New translations en.yml (Indonesian) [ci skip] * New translations en.json (Occitan) [ci skip] * New translations devise.en.yml (Romanian) [ci skip] * New translations en.json (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.json (Albanian) [ci skip] * New translations doorkeeper.en.yml (Albanian) [ci skip] * New translations en.json (Sardinian) [ci skip] * New translations en.yml (Sardinian) [ci skip] * New translations simple_form.en.yml (Sardinian) [ci skip] * New translations activerecord.en.yml (Sardinian) [ci skip] * New translations devise.en.yml (Sardinian) [ci skip] * New translations doorkeeper.en.yml (Sardinian) [ci skip] * New translations activerecord.en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.json (Sardinian) [ci skip] * New translations activerecord.en.yml (Sardinian) [ci skip] * New translations simple_form.en.yml (Romanian) [ci skip] * New translations en.json (Slovenian) [ci skip] * New translations en.yml (Slovenian) [ci skip] * New translations en.json (Thai) [ci skip] * New translations en.yml (Thai) [ci skip] * New translations en.yml (Esperanto) [ci skip] * New translations simple_form.en.yml (Romanian) [ci skip] * New translations doorkeeper.en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations doorkeeper.en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations en.json (Romanian) [ci skip] * New translations en.yml (Romanian) [ci skip] * New translations simple_form.en.yml (Romanian) [ci skip] * New translations en.json (Chinese Simplified) [ci skip] * New translations en.yml (Chinese Simplified) [ci skip] * New translations en.yml (Thai) [ci skip] * New translations devise.en.yml (Chinese Simplified) [ci skip] * New translations en.yml (Thai) [ci skip] * New translations en.yml (Arabic) [ci skip] * New translations simple_form.en.yml (Arabic) [ci skip] * New translations simple_form.en.yml (Thai) [ci skip] * New translations en.yml (Slovak) [ci skip] * New translations en.yml (Indonesian) [ci skip] * New translations en.json (Occitan) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations en.json (Slovak) [ci skip] * New translations doorkeeper.en.yml (Czech) [ci skip] * New translations simple_form.en.yml (Russian) [ci skip] * New translations simple_form.en.yml (Ukrainian) [ci skip] * New translations en.json (Hungarian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations simple_form.en.yml (Hungarian) [ci skip] * New translations en.yml (Japanese) [ci skip] * New translations simple_form.en.yml (Chinese Simplified) [ci skip] * New translations en.yml (Persian) [ci skip] * New translations simple_form.en.yml (Chinese Simplified) [ci skip] * New translations en.json (French) [ci skip] * New translations simple_form.en.yml (Ukrainian) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.yml (Ukrainian) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.yml (Norwegian Nynorsk) [ci skip] * New translations simple_form.en.yml (Norwegian Nynorsk) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations simple_form.en.yml (Russian) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations en.yml (Catalan) [ci skip] * New translations en.yml (Greek) [ci skip] * New translations en.yml (Korean) [ci skip] * New translations en.yml (Corsican) [ci skip] * New translations en.yml (Spanish) [ci skip] * New translations en.yml (Icelandic) [ci skip] * New translations en.yml (Arabic) [ci skip] * New translations devise.en.yml (Arabic) [ci skip] * New translations en.yml (Japanese) [ci skip] * New translations en.yml (Galician) [ci skip] * New translations en.yml (Portuguese) [ci skip] * New translations en.yml (Thai) [ci skip] * New translations en.yml (Italian) [ci skip] * New translations en.yml (Russian) [ci skip] * New translations en.yml (French) [ci skip] * New translations en.yml (Spanish, Argentina) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.yml (Ukrainian) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.yml (Hungarian) [ci skip] * New translations en.json (Finnish) [ci skip] * New translations doorkeeper.en.yml (Finnish) [ci skip] * New translations en.json (Sardinian) [ci skip] * New translations en.yml (Ukrainian) [ci skip] * New translations simple_form.en.yml (Ukrainian) [ci skip] * New translations en.json (Ukrainian) [ci skip] * New translations en.yml (Ukrainian) [ci skip] * New translations en.yml (Chinese Simplified) [ci skip] * New translations devise.en.yml (Chinese Simplified) [ci skip] * New translations devise.en.yml (Chinese Simplified) [ci skip] * New translations en.yml (Portuguese, Brazilian) [ci skip] * New translations en.json (Japanese) [ci skip] * New translations en.yml (Chinese Simplified) [ci skip] * i18n-tasks normalize * yarn manage:translations
2020-05-13Change “hide/show boosts from …” menu to be hidden when the account is ↵ThibG
muted (#13748) Otherwise, it may mislead users into believing this setting is an exception to the muting behavior. Fixes #13744
2020-05-13Fix some account avatars on public pages having incorrect size (#13692)ThibG
* Fix some account avatars on public pages having incorrect size * Remove outdated and overridden width and height attributes * Remove more hardcoded width/height attributes
2020-05-12Fix RedownloadMediaWorker (#13741)Takeshi Umeda
2020-05-12Fix first poll option not being focused when adding a poll (#13740)ThibG
Fixes #13698
2020-05-12Fix keybase config serializer (#13742)Takeshi Umeda
2020-05-12Bump doorkeeper from 5.3.3 to 5.4.0 (#13733)dependabot-preview[bot]
* Bump doorkeeper from 5.3.3 to 5.4.0 Bumps [doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) from 5.3.3 to 5.4.0. - [Release notes](https://github.com/doorkeeper-gem/doorkeeper/releases) - [Changelog](https://github.com/doorkeeper-gem/doorkeeper/blob/master/CHANGELOG.md) - [Commits](https://github.com/doorkeeper-gem/doorkeeper/compare/v5.3.3...v5.4.0) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> * Fix tests * Fix use of Doorkeeper::AccessToken.find_or_create_for * Fix tests? Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: Thibaut Girka <thib@sitedethib.com>
2020-05-12Fix not publishing update of remote timeline (#13745)Takeshi Umeda
* Fix not publishing update of remote timeline * fix @ missing * if/unless to if/else
2020-05-11Fix sr locale being selected over sr-Latn (#13693)ThibG
* Fix sr locale being selected over sr-Latn * Update tests
2020-05-10Refactor monkey-patching of Goldfinger (#12561)Eugen Rochko
2020-05-10Add `vi` to available locales (#13542)taicv
* Enable selecting Vietnamese language in Admin Dashboard * Update settings_helper.rb Co-authored-by: Eugen Rochko <eugen@zeonfederated.com>
2020-05-10Add ability to remove identity proofs from account (#13682)Eugen Rochko
Fix #12613
2020-05-10Add remote only to public timeline (#13504)Takeshi Umeda
* Add remote only to public timeline * Fix code style
2020-05-10Fix error within error when limiting backtrace to 3 lines (#13120)Eugen Rochko
Fix #13086, close #13113
2020-05-10Remove confusing “You are already signed in.” flash message (#13547)ThibG
When attempting to access the log-in page while already logged in, Devise's `require_no_authentication` kicks in and sets a flash message “You are already signed in.” In almost all cases, this also causes a redirect to /web, which does not display or clear flash messages, thus leaving the message to a potentially much later date, like for instance, accessing /preferences several minutes after being redirected to /web.
2020-05-10Improve RSS entries for statuses (#13592)ThibG
* Improve RSS entries for statuses - Render polls in both accounts and tags serializers - Refactor RSS serializers - Change title preview to include ellipsis when truncated - Change title preview to show CW instead of toot text - Add tests * Remove title from OEmbed serialization Twitter doesn't serialize title either, and tihs allows us to move the title formatting code to the RSS serializers.
2020-05-08Remove 'unsafe-inline' from Content-Security-Policy style-src (#13679)ThibG
* Make sure wicg-inert doesn't rely on inline CSS * Remove unsafe-inline from style-src
2020-05-08Fix failing jest test (#13681)Eugen Rochko
2020-05-08Fix own following/followers not showing muted users (#13614)ThibG
Fixes #13612
2020-05-08Fix followings list order | Issue #13538 (#13676)Taras Gogol
2020-05-03Add more ActivityPub controller tests (#13590)Eugen Rochko
2020-05-03Fix use of inline CSS in public pages (#13576)ThibG
Change `account_link_to` to use an image tag rather than some inline CSS. Dropped the `size` parameter in the process, but it wasn't used for anything except the default value of 36px. Dropped CSS rules that were always overriden, and defaulted to 36px width and height instead.
2020-05-03Revert "improve status title (#8596)" (#13591)Yamagishi Kazutoshi
This reverts commit 05756c9a14864655ae6777505a4ee5cfa9b0ee93.
2020-05-03Add more tests for ActivityPub controllers (#13585)Eugen Rochko
2020-04-30Only check locally when deduplicating usernames (#13581)kaiyou
When deduplicating account usernames for OAuthable users, the routine did check if any account was known with that username, including remote accounts. This caused some unnecessary deduplication, and usernames ending with unexpected trailing _1. This fixes #13580
2020-04-28Fix admin-facing uses of inline CSS (#13575)ThibG
* Move .back-button inline styles to CSS file All occurrences of the back-button CSS class used the same inline CSS rules, so moved them over to the CSS file * Fix “Add new domain block” button using inline CSS * Replace common pattern of inline-styled button boxes by a CSS class In particular, switching from `float: left/right` to a flexbox with `justify-content: space-between`. This implied changing the order of a few HTML tags and adding an empty `div` in one case. Also removed a `margin-bottom` rule that wasn't needed due to the margins of surrounding elements. * Move account admin view inline CSS to CSS file
2020-04-28Fix page incorrectly scrolling when bringing up dropdown menus (#13574)ThibG
Fixes #13573 For some reason (I suspect this may be related to focusing the item before it got drown by the browser), Firefox scrolls to top when bringing up dropdown menus with pre-selected items. This commit uses the “preventScroll” option as, due to the placement behavior, the menu should be visible anyway and not trigger scrolling.
2020-04-28Fix end-user-facing uses of inline CSS (#13438)ThibG
* Move some inline styles to CSS files * Move default_account_display_name span to fix useless tags with duplicate id * Change handling of public pages spoiler text from inline CSS to dataset attribute * Use the `dir` HTML attribute instead of inline CSS * Move status action bar inline CSS to CSS file * Hide logo resources from CSS file, not inline CSS Fixes #11601 * Move translation prompt styling from inline CSS to CSS file * Move “invited by” styling on registration form from inline to CSS file * Use the progress tag to display poll results in JS fallback * Fix poll results JS-less fallback when the user has voted for an option * Change account public page “moved” notice to use img tags instead of inline CSS * Move OTP hint inline CSS to SCSS file * Hide JS-less fallback vote progressbars from accessibility tools Co-authored-by: Eugen Rochko <eugen@zeonfederated.com>
2020-04-28Refactor/cleanup TIMELINE_DELETE-related code (#13175)ThibG
2020-04-28Fix messed up z-index when NoScript blocks media/previews (#13449)ThibG
Fixes #13444
2020-04-28Fix /public showing public instead of community timeline for logged-in users ↵ThibG
(#13499)
2020-04-28Add `invites_enabled` to API (#13501)ThibG
2020-04-26Add separate cache directory for non-local uploads (#12821)Eugen Rochko
2020-04-25Fix not being able to resolve public resources in development environment ↵Eugen Rochko
(#13505)
2020-04-25Fix uninformative error message when uploading unsupported image files (#13540)ThibG
Attempting to upload image files that the browser is unable to load results in “Oops! An unexpected error occurred.” This commit changes the error handling so that an unprocessable image results in the file being sent anyway, which might cover a few corner cases, and provide a slightly better error message.
2020-04-25Fix expanded video player issues (#13541)ThibG
Fixes #13536 - Expanding a paused video doesn't autoplay anymore - Default volume level for the expanded video inherited from the original video Position/playing state/volume are carried over from the original video player to the modal, but they're not reported back to the modal as it would require deeper changes.
2020-04-23Fix enable/disable relay failures (#13535)Takeshi Umeda
2020-04-23Set max-width and max-height to gif video (#13533)Irie Aoi
2020-04-21Fix and refactor keyboard navigation in dropdown menus (#13528)ThibG
Fixes #13527 - Fixes caught keyboard events being needlessly propagated - Let up/down arrows wrap around like the tab key does - Refactor common code
2020-04-20Allow users to delete their header and avatar (#13234)sternenseemann
This is achieved by sending a DELETE request to /settings/profile/pictures/{avatar,header} via a link that is part of the upload form's hint of the respective picture.
2020-04-19Update Twemoji to 12.1.5 (#13021)D Anzorge
* Update Twemoji to 12.1.5 SVGs from Twemoji repo https://github.com/twitter/twemoji * Update emoji_map.json to Unicode 12
2020-04-18Add local only to hashtag timeline (#13502)Takeshi Umeda
2020-04-18Fix uploaded image orientation in some browsers (#13493)ThibG
Some browsers (at least recent Chrome versions) automatically take image metadata into account when drawing images into a canvas. There seem to be no way to prevent that behavior, and the only way to detect it seems to compare with a known image. See: https://github.com/w3c/csswg-drafts/issues/4666 Solution adapted from: https://github.com/blueimp/JavaScript-Load-Image/commit/1e4df707821a0afcc11ea0720ee403b8759f3881
2020-04-17Fix not being able to vote (#13490)ThibG
Fix regression introduced by ab8d7c0680d7f75826277be4c8eea1ebd396be8a
2020-04-17Fix admin actions log crash when displaying updates of deleted announcements ↵ThibG
(#13489) Fixes #13487
2020-04-16Fix Poll fetchPoll action not being debounced. (#13485)Gurgen Hayrapetyan
* Fix Poll fetchPoll action not being debounced. * Fix unused import in the Poll component
2020-04-16Fix DeliveryWorker not to call failure_tracker when inbox_url is unavailable ↵Takeshi Umeda
(#13482)
2020-04-15Fix confusing error when failing to add an alias to an unknown account (#13480)ThibG
Follow-up to #13452, fixing broken `uri.nil?` test. Also remove the separate check for `uri` presence, as that would result in a “Please review 2 errors below” while only one would be listed.
2020-04-15Change delivery failure tracking to work with hostnames instead of URLs (#13437)Eugen Rochko
2020-04-15Fix “Email changed” notification sometimes having wrong e-mail (#13475)ThibG
* Fix “Email changed” notification sometimes having wrong e-mail Fixes #6778 The root of the issue is that `send_devise_notification` was called before the changes were properly commited to the database, causing the mailer to pick previous values if running too early. Devise's documentation provides guidance on how to handle that[1][2], however, I have found it to not be working, as the following happens, in that order: - `send_devise_notification` is called for the `email_changed` notification. In that case, `changed?` is false and `saved_changes?` is true, so if we use the former, we have the same issue. - the `after_commit` hook is called - `send_devise_notification` is called for the `confirmation_instructions` notification. In that case, `changed?` is still false, and `saved_changes?` still true, so if we use the latter, that second notification email is simply not going to be sent (as we would be queuing the notification *after* executing the after_commit hook). This is because it may be called from either an `after_update` or `after_commit` hook, the difference not being a call to `save` but the transaction actually being committed to the database. This may arguably be a bug in Devise, or Devise's notification. The proposed workaround is inspired by Devise's documentation but checks whether a transaction is open to make the call whether to immediately send the notification or defer it to the `after_commit` hook. [1]: https://www.rubydoc.info/github/plataformatec/devise/Devise%2FModels%2FAuthenticatable:send_devise_notification [2]: https://github.com/heartcombo/devise/blob/406915cb781e38255a30ad2a0609e33952b9ec50/lib/devise/models/authenticatable.rb#L133-L194 * Fix cases when sending notifications without changing the model * Defer sending if and only if in transaction including current record