From 628da11e38b0580a074268f32d09791ed6278def Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 17 Dec 2018 03:14:13 +0100 Subject: Do no retry web push workers if the server returns a 4xx response (#9434) Add timeout of 10s to web push requests --- app/models/web/push_subscription.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'app/models') diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb index d19b20c48..b57807d1c 100644 --- a/app/models/web/push_subscription.rb +++ b/app/models/web/push_subscription.rb @@ -68,6 +68,9 @@ class Web::PushSubscription < ApplicationRecord p256dh: key_p256dh, auth: key_auth, ttl: ttl, + ssl_timeout: 10, + open_timeout: 10, + read_timeout: 10, vapid: { subject: "mailto:#{::Setting.site_contact_email}", private_key: Rails.configuration.x.vapid_private_key, -- cgit From 087e11897137dc1f2811c21c3ccc6cec3ccdedb3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 17 Dec 2018 03:14:28 +0100 Subject: Remove "most popular" tab from profile directory, add responsive design (#9539) * Remove "most popular" tab from profile directory, add responsive design * Remove unused translations --- app/controllers/directories_controller.rb | 12 +------ app/javascript/styles/mastodon/containers.scss | 6 ++++ app/javascript/styles/mastodon/widgets.scss | 43 ++++++++++++++++++-------- app/models/account.rb | 3 +- app/views/directories/index.html.haml | 8 ++--- app/views/layouts/public.html.haml | 6 ++-- config/locales/ar.yml | 1 - config/locales/co.yml | 2 -- config/locales/cs.yml | 2 -- config/locales/el.yml | 2 -- config/locales/en.yml | 2 -- config/locales/eu.yml | 2 -- config/locales/fr.yml | 2 -- config/locales/gl.yml | 2 -- config/locales/ja.yml | 2 -- config/locales/nl.yml | 2 -- config/locales/oc.yml | 2 -- config/locales/pl.yml | 2 -- config/locales/sk.yml | 2 -- config/routes.rb | 2 -- 20 files changed, 43 insertions(+), 62 deletions(-) (limited to 'app/models') diff --git a/app/controllers/directories_controller.rb b/app/controllers/directories_controller.rb index b8565af4b..df012657a 100644 --- a/app/controllers/directories_controller.rb +++ b/app/controllers/directories_controller.rb @@ -32,22 +32,12 @@ class DirectoriesController < ApplicationController end def set_accounts - @accounts = Account.searchable.discoverable.page(params[:page]).per(50).tap do |query| + @accounts = Account.discoverable.page(params[:page]).per(30).tap do |query| query.merge!(Account.tagged_with(@tag.id)) if @tag - - if popular_requested? - query.merge!(Account.popular) - else - query.merge!(Account.by_recent_status) - end end end def set_instance_presenter @instance_presenter = InstancePresenter.new end - - def popular_requested? - request.path.ends_with?('/popular') - end end diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss index 44fc1e538..8de53ca98 100644 --- a/app/javascript/styles/mastodon/containers.scss +++ b/app/javascript/styles/mastodon/containers.scss @@ -294,6 +294,12 @@ text-decoration: underline; color: $primary-text-color; } + + @media screen and (max-width: $no-gap-breakpoint) { + &.optional { + display: none; + } + } } .nav-button { diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss index c863e3b4f..87e633c70 100644 --- a/app/javascript/styles/mastodon/widgets.scss +++ b/app/javascript/styles/mastodon/widgets.scss @@ -229,18 +229,6 @@ margin-bottom: 10px; } -.moved-account-widget, -.memoriam-widget, -.box-widget, -.contact-widget, -.landing-page__information.contact-widget { - @media screen and (max-width: $no-gap-breakpoint) { - margin-bottom: 0; - box-shadow: none; - border-radius: 0; - } -} - .page-header { background: lighten($ui-base-color, 8%); box-shadow: 0 0 15px rgba($base-shadow-color, 0.2); @@ -261,11 +249,20 @@ font-size: 15px; color: $darker-text-color; } + + @media screen and (max-width: $no-gap-breakpoint) { + margin-top: 0; + background: lighten($ui-base-color, 4%); + + h1 { + font-size: 24px; + } + } } .directory { background: $ui-base-color; - border-radius: 0 0 4px 4px; + border-radius: 4px; box-shadow: 0 0 15px rgba($base-shadow-color, 0.2); &__tag { @@ -407,4 +404,24 @@ font-size: 14px; } } + + @media screen and (max-width: $no-gap-breakpoint) { + tbody td.optional { + display: none; + } + } +} + +.moved-account-widget, +.memoriam-widget, +.box-widget, +.contact-widget, +.landing-page__information.contact-widget, +.directory, +.page-header { + @media screen and (max-width: $no-gap-breakpoint) { + margin-bottom: 0; + box-shadow: none; + border-radius: 0; + } } diff --git a/app/models/account.rb b/app/models/account.rb index 9767e3767..a47741611 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -91,9 +91,8 @@ class Account < ApplicationRecord scope :matches_display_name, ->(value) { where(arel_table[:display_name].matches("#{value}%")) } scope :matches_domain, ->(value) { where(arel_table[:domain].matches("%#{value}%")) } scope :searchable, -> { where(suspended: false).where(moved_to_account_id: nil) } - scope :discoverable, -> { where(silenced: false).where(discoverable: true).joins(:account_stat).where(AccountStat.arel_table[:followers_count].gteq(MIN_FOLLOWERS_DISCOVERY)) } + scope :discoverable, -> { searchable.where(silenced: false).where(discoverable: true).joins(:account_stat).where(AccountStat.arel_table[:followers_count].gteq(MIN_FOLLOWERS_DISCOVERY)).by_recent_status } scope :tagged_with, ->(tag) { joins(:accounts_tags).where(accounts_tags: { tag_id: tag }) } - scope :popular, -> { order('account_stats.followers_count desc') } scope :by_recent_status, -> { order(Arel.sql('(case when account_stats.last_status_at is null then 1 else 0 end) asc, account_stats.last_status_at desc')) } delegate :email, diff --git a/app/views/directories/index.html.haml b/app/views/directories/index.html.haml index f70eb964a..88706def7 100644 --- a/app/views/directories/index.html.haml +++ b/app/views/directories/index.html.haml @@ -16,10 +16,6 @@ .grid .column-0 - .account__section-headline - = active_link_to t('directories.most_recently_active'), @tag ? explore_hashtag_path(@tag) : explore_path - = active_link_to t('directories.most_popular'), @tag ? explore_hashtag_popular_path(@tag) : explore_popular_path - - if @accounts.empty? = nothing_here - else @@ -29,10 +25,10 @@ - @accounts.each do |account| %tr %td= account_link_to account - %td.accounts-table__count + %td.accounts-table__count.optional = number_to_human account.statuses_count, strip_insignificant_zeros: true %small= t('accounts.posts', count: account.statuses_count).downcase - %td.accounts-table__count + %td.accounts-table__count.optional = number_to_human account.followers_count, strip_insignificant_zeros: true %small= t('accounts.followers', count: account.followers_count).downcase %td.accounts-table__count diff --git a/app/views/layouts/public.html.haml b/app/views/layouts/public.html.haml index 93ed12f18..caccd5bb6 100644 --- a/app/views/layouts/public.html.haml +++ b/app/views/layouts/public.html.haml @@ -10,9 +10,9 @@ = image_tag asset_pack_path('logo_full.svg'), alt: 'Mastodon' - if Setting.profile_directory - = link_to t('directories.directory'), explore_path, class: 'nav-link' - = link_to t('about.about_this'), about_more_path, class: 'nav-link' - = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link' + = link_to t('directories.directory'), explore_path, class: 'nav-link optional' + = link_to t('about.about_this'), about_more_path, class: 'nav-link optional' + = link_to t('about.apps'), 'https://joinmastodon.org/apps', class: 'nav-link optional' .nav-center .nav-right - if user_signed_in? diff --git a/config/locales/ar.yml b/config/locales/ar.yml index eda99e24c..4de1e4e26 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -541,7 +541,6 @@ ar: warning_title: توافر المحتوى المنشور و المبعثَر directories: explore_mastodon: استكشف %{title} - most_popular: المشهورة errors: '403': ليس لك الصلاحيات الكافية لعرض هذه الصفحة. '404': إنّ الصفحة التي تبحث عنها لا وجود لها أصلا. diff --git a/config/locales/co.yml b/config/locales/co.yml index d2dcef9a4..80d2decd3 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -531,8 +531,6 @@ co: directory: Annuariu di i prufili explanation: Scopre utilizatori à partesi di i so centri d'interessu explore_mastodon: Scopre à %{title} - most_popular: I più pupulari - most_recently_active: Attività a più fresca people: one: "%{count} persona" other: "%{count} persone" diff --git a/config/locales/cs.yml b/config/locales/cs.yml index a5a3c0184..1bba55f0f 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -536,8 +536,6 @@ cs: directory: Adresář profilů explanation: Objevujte uživatele podle jejich zájmů explore_mastodon: Prozkoumejte %{title} - most_popular: Nejpopulárnější - most_recently_active: Naposledy aktivní people: few: "%{count} lidé" one: "%{count} člověk" diff --git a/config/locales/el.yml b/config/locales/el.yml index 342cad91c..9d41f353f 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -531,8 +531,6 @@ el: directory: Κατάλογος λογαριασμών explanation: Βρες χρήστες βάσει των ενδιαφερόντων τους explore_mastodon: Εξερεύνησε %{title} - most_popular: Δημοφιλείς - most_recently_active: Πρόσφατα ενεργοί people: one: "%{count} άτομο" other: "%{count} άτομα" diff --git a/config/locales/en.yml b/config/locales/en.yml index 314787acd..c8bfccdf7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -535,8 +535,6 @@ en: directory: Profile directory explanation: Discover users based on their interests explore_mastodon: Explore %{title} - most_popular: Most popular - most_recently_active: Most recently active people: one: "%{count} person" other: "%{count} people" diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 15307c76e..c96438bc3 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -531,8 +531,6 @@ eu: directory: Profilen direktorioa explanation: Deskubritu erabiltzaileak interesen arabera explore_mastodon: Esploratu %{title} - most_popular: Puri-purian - most_recently_active: Azkenaldian aktibo people: one: pertsona %{count} other: "%{count} pertsona" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index de3070e8a..c171d9342 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -531,8 +531,6 @@ fr: directory: Annuaire des profils explanation: Découvrir des utilisateurs en se basant sur leurs centres d'intérêt explore_mastodon: Explorer %{title} - most_popular: Les plus populaires - most_recently_active: Les actifs les plus récents people: one: "%{count} personne" other: "%{count} personne" diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 8f12587d6..5f4e420cb 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -531,8 +531,6 @@ gl: directory: Directorio de perfil explanation: Descubra usuarias según o seu interese explore_mastodon: Explorar %{title} - most_popular: Máis popular - most_recently_active: Máis activa recentemente people: one: "%{count} persoa" other: "%{count} persoas" diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 50e9522bc..9c8d7f5b9 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -530,8 +530,6 @@ ja: directories: directory: ディレクトリ explore_mastodon: "%{title}を探索" - most_popular: 人気順 - most_recently_active: 直近の活動順 people: one: "%{count} 人" other: "%{count} 人" diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 30af6562a..b5229d241 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -531,8 +531,6 @@ nl: directory: Gebruikersgids explanation: Ontdek gebruikers aan de hand van hun interesses explore_mastodon: "%{title} verkennen" - most_popular: Meest populair - most_recently_active: Recentelijk actief people: one: "%{count} gebruikers" other: "%{count} gebruikers" diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 8fe3e350a..9015997fc 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -587,8 +587,6 @@ oc: directory: Annuari de perfils explanation: Trobar d’utilizaires segon lor interèsses explore_mastodon: Explorar %{title} - most_popular: Mai populars - most_recently_active: Mai actius recentament people: one: "%{count} persona" other: "%{count} personas" diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 4a0d65440..79ba6f9fb 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -541,8 +541,6 @@ pl: directory: Katalog profilów explanation: Poznaj profile na podstawie zainteresowań explore_mastodon: Odkrywaj %{title} - most_popular: Napopularniejsi - most_recently_active: Ostatnio aktywni people: few: "%{count} osoby" many: "%{count} osób" diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 5f49a2d0e..bea4ac334 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -536,8 +536,6 @@ sk: directory: Databáza profilov explanation: Pátraj po užívateľoch podľa ich záujmov explore_mastodon: Prebádaj %{title} - most_popular: Najpopulárnejšie - most_recently_active: Naposledy aktívni people: few: "%{count} ľudia" one: "%{count} človek" diff --git a/config/routes.rb b/config/routes.rb index 4a0289465..0aba433e2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -81,9 +81,7 @@ Rails.application.routes.draw do post '/interact/:id', to: 'remote_interaction#create' get '/explore', to: 'directories#index', as: :explore - get '/explore/popular', to: 'directories#index', as: :explore_popular get '/explore/:id', to: 'directories#show', as: :explore_hashtag - get '/explore/:id/popular', to: 'directories#show', as: :explore_hashtag_popular namespace :settings do resource :profile, only: [:show, :update] -- cgit From adaf249700a5384b817de12bc43ca67fcdc6f257 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 17 Dec 2018 04:32:36 +0100 Subject: Fix regression in #9539 (#9541) --- app/models/account.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/models') diff --git a/app/models/account.rb b/app/models/account.rb index a47741611..5a7a9c580 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -94,6 +94,7 @@ class Account < ApplicationRecord scope :discoverable, -> { searchable.where(silenced: false).where(discoverable: true).joins(:account_stat).where(AccountStat.arel_table[:followers_count].gteq(MIN_FOLLOWERS_DISCOVERY)).by_recent_status } scope :tagged_with, ->(tag) { joins(:accounts_tags).where(accounts_tags: { tag_id: tag }) } scope :by_recent_status, -> { order(Arel.sql('(case when account_stats.last_status_at is null then 1 else 0 end) asc, account_stats.last_status_at desc')) } + scope :popular, -> { order('account_stats.followers_count desc') } delegate :email, :unconfirmed_email, -- cgit From a1c56fcef124b08fc2676d38fd79ed72d660d865 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Mon, 17 Dec 2018 20:36:30 +0100 Subject: Add admin setting to disable followers count --- app/controllers/admin/settings_controller.rb | 2 ++ app/controllers/follower_accounts_controller.rb | 2 +- app/helpers/stream_entries_helper.rb | 12 +++++++----- app/models/form/admin_settings.rb | 2 ++ app/serializers/rest/account_serializer.rb | 4 ++++ app/views/accounts/_header.html.haml | 4 ++-- app/views/admin/settings/edit.html.haml | 3 +++ app/views/directories/index.html.haml | 7 ++++--- config/locales/en.yml | 3 +++ config/settings.yml | 1 + 10 files changed, 29 insertions(+), 11 deletions(-) (limited to 'app/models') diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb index 76b3c3a2b..9624df96b 100644 --- a/app/controllers/admin/settings_controller.rb +++ b/app/controllers/admin/settings_controller.rb @@ -29,6 +29,7 @@ module Admin preview_sensitive_media custom_css profile_directory + hide_followers_count ).freeze BOOLEAN_SETTINGS = %w( @@ -41,6 +42,7 @@ module Admin show_known_fediverse_at_about_page preview_sensitive_media profile_directory + hide_followers_count ).freeze UPLOAD_SETTINGS = %w( diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index 461e6d70e..13043b1b9 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -37,7 +37,7 @@ class FollowerAccountsController < ApplicationController def collection_presenter options = { type: :ordered } - options[:size] = @account.followers_count + options[:size] = @account.followers_count unless Setting.hide_followers_count if params[:page].present? ActivityPub::CollectionPresenter.new( id: account_followers_url(@account, page: params.fetch(:page, 1)), diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index 033d435c4..e37cfbda4 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -61,7 +61,7 @@ module StreamEntriesHelper end def account_description(account) - prepend_str = [ + prepend_stats = [ [ number_to_human(account.statuses_count, strip_insignificant_zeros: true), I18n.t('accounts.posts', count: account.statuses_count), @@ -71,14 +71,16 @@ module StreamEntriesHelper number_to_human(account.following_count, strip_insignificant_zeros: true), I18n.t('accounts.following', count: account.following_count), ].join(' '), + ] - [ + unless Setting.hide_followers_count + prepend_stats << [ number_to_human(account.followers_count, strip_insignificant_zeros: true), I18n.t('accounts.followers', count: account.followers_count), - ].join(' '), - ].join(', ') + ].join(' ') + end - [prepend_str, account.note].join(' · ') + [prepend_stats.join(', '), account.note].join(' · ') end def media_summary(status) diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 34c75e3bf..d568200ed 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -30,6 +30,8 @@ class Form::AdminSettings :show_staff_badge=, :bootstrap_timeline_accounts, :bootstrap_timeline_accounts=, + :hide_followers_count, + :hide_followers_count=, :flavour, :flavour=, :skin, diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 12adc971c..a3f2ad036 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -51,4 +51,8 @@ class REST::AccountSerializer < ActiveModel::Serializer def moved_and_not_nested? object.moved? && object.moved_to_account.moved_to_account_id.nil? end + + def followers_count + Setting.hide_followers_count ? -1 : object.followers_count + end end diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index 370e7e470..458c86ce5 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -24,8 +24,8 @@ %span.counter-label= t('accounts.following', count: account.following_count) .counter{ class: active_nav_class(account_followers_url(account)) } - = link_to account_followers_url(account), title: number_with_delimiter(account.followers_count) do - %span.counter-number= number_to_human account.followers_count, strip_insignificant_zeros: true + = link_to account_followers_url(account), title: Setting.hide_followers_count ? nil : number_with_delimiter(account.followers_count) do + %span.counter-number= Setting.hide_followers_count ? '-' : (number_to_human account.followers_count, strip_insignificant_zeros: true) %span.counter-label= t('accounts.followers', count: account.followers_count) .spacer .public-account-header__tabs__tabs__buttons diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index bcf57aac0..e3ceb4344 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -65,6 +65,9 @@ .fields-group = f.input :profile_directory, as: :boolean, wrapper: :with_label, label: t('admin.settings.profile_directory.title'), hint: t('admin.settings.profile_directory.desc_html') + .fields-group + = f.input :hide_followers_count, as: :boolean, wrapper: :with_label, label: t('admin.settings.hide_followers_count.title'), hint: t('admin.settings.hide_followers_count.desc_html') + %hr.spacer/ .fields-group diff --git a/app/views/directories/index.html.haml b/app/views/directories/index.html.haml index 88706def7..7f6ad13e6 100644 --- a/app/views/directories/index.html.haml +++ b/app/views/directories/index.html.haml @@ -28,9 +28,10 @@ %td.accounts-table__count.optional = number_to_human account.statuses_count, strip_insignificant_zeros: true %small= t('accounts.posts', count: account.statuses_count).downcase - %td.accounts-table__count.optional - = number_to_human account.followers_count, strip_insignificant_zeros: true - %small= t('accounts.followers', count: account.followers_count).downcase + - unless Setting.hide_followers_count + %td.accounts-table__count.optional + = number_to_human account.followers_count, strip_insignificant_zeros: true + %small= t('accounts.followers', count: account.followers_count).downcase %td.accounts-table__count - if account.last_status_at.present? %time.time-ago{ datetime: account.last_status_at.iso8601, title: l(account.last_status_at) }= l account.last_status_at diff --git a/config/locales/en.yml b/config/locales/en.yml index 735a88efd..e722788fe 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -370,6 +370,9 @@ en: hero: desc_html: Displayed on the frontpage. At least 600x100px recommended. When not set, falls back to instance thumbnail title: Hero image + hide_followers_count: + desc_html: Do not show followers count on user profiles + title: Hide followers count mascot: desc_html: Displayed on multiple pages. At least 293×205px recommended. When not set, falls back to default mascot title: Mascot image diff --git a/config/settings.yml b/config/settings.yml index 2cac28b63..bd6578bd4 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -34,6 +34,7 @@ defaults: &defaults reduce_motion: false system_font_ui: false noindex: false + hide_followers_count: false flavour: 'glitch' skin: 'default' aggregate_reblogs: true -- cgit From bd23288a527bbbe0f8dcdf2a6ad3a585e4aed740 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 18 Dec 2018 11:24:44 +0100 Subject: Add a per-user setting to hide followers count This is only available if the instance-wide setting isn't set and allows people to hide their own followers count. This does not hide others' to them. --- app/controllers/follower_accounts_controller.rb | 2 +- app/controllers/settings/preferences_controller.rb | 1 + app/helpers/stream_entries_helper.rb | 2 +- app/lib/user_settings_decorator.rb | 5 +++++ app/models/user.rb | 2 +- app/serializers/rest/account_serializer.rb | 2 +- app/views/accounts/_header.html.haml | 4 ++-- app/views/directories/index.html.haml | 2 +- app/views/settings/preferences/show.html.haml | 4 ++++ config/locales/simple_form.en.yml | 1 + 10 files changed, 18 insertions(+), 7 deletions(-) (limited to 'app/models') diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index 13043b1b9..f985f0eff 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -37,7 +37,7 @@ class FollowerAccountsController < ApplicationController def collection_presenter options = { type: :ordered } - options[:size] = @account.followers_count unless Setting.hide_followers_count + options[:size] = @account.followers_count unless Setting.hide_followers_count || @account.user&.setting_hide_followers_count if params[:page].present? ActivityPub::CollectionPresenter.new( id: account_followers_url(@account, page: params.fetch(:page, 1)), diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index b70844b65..d4932afd6 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -43,6 +43,7 @@ class Settings::PreferencesController < Settings::BaseController :setting_system_font_ui, :setting_noindex, :setting_hide_network, + :setting_hide_followers_count, :setting_aggregate_reblogs, notification_emails: %i(follow follow_request reblog favourite mention digest report), interactions: %i(must_be_follower must_be_following) diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index e37cfbda4..fce03d03e 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -73,7 +73,7 @@ module StreamEntriesHelper ].join(' '), ] - unless Setting.hide_followers_count + unless Setting.hide_followers_count || account.user&.setting_hide_followers_count prepend_stats << [ number_to_human(account.followers_count, strip_insignificant_zeros: true), I18n.t('accounts.followers', count: account.followers_count), diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 559e00d20..569255f6e 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -30,6 +30,7 @@ class UserSettingsDecorator user.settings['reduce_motion'] = reduce_motion_preference if change?('setting_reduce_motion') user.settings['system_font_ui'] = system_font_ui_preference if change?('setting_system_font_ui') user.settings['noindex'] = noindex_preference if change?('setting_noindex') + user.settings['hide_followers_count']= hide_followers_count_preference if change?('setting_hide_followers_count') user.settings['flavour'] = flavour_preference if change?('setting_flavour') user.settings['skin'] = skin_preference if change?('setting_skin') user.settings['hide_network'] = hide_network_preference if change?('setting_hide_network') @@ -92,6 +93,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_noindex' end + def hide_followers_count_preference + boolean_cast_setting 'setting_hide_followers_count' + end + def flavour_preference settings['setting_flavour'] end diff --git a/app/models/user.rb b/app/models/user.rb index 66896257a..a6c25342a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -94,7 +94,7 @@ class User < ApplicationRecord has_many :session_activations, dependent: :destroy delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :favourite_modal, :delete_modal, - :reduce_motion, :system_font_ui, :noindex, :flavour, :skin, :display_media, :hide_network, + :reduce_motion, :system_font_ui, :noindex, :flavour, :skin, :display_media, :hide_network, :hide_followers_count, :expand_spoilers, :default_language, :aggregate_reblogs, to: :settings, prefix: :setting, allow_nil: false attr_reader :invite_code diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index a3f2ad036..c34d23452 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -53,6 +53,6 @@ class REST::AccountSerializer < ActiveModel::Serializer end def followers_count - Setting.hide_followers_count ? -1 : object.followers_count + (Setting.hide_followers_count || object.user&.setting_hide_followers_count) ? -1 : object.followers_count end end diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index 458c86ce5..87cb0a91f 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -24,8 +24,8 @@ %span.counter-label= t('accounts.following', count: account.following_count) .counter{ class: active_nav_class(account_followers_url(account)) } - = link_to account_followers_url(account), title: Setting.hide_followers_count ? nil : number_with_delimiter(account.followers_count) do - %span.counter-number= Setting.hide_followers_count ? '-' : (number_to_human account.followers_count, strip_insignificant_zeros: true) + = link_to account_followers_url(account), title: (Setting.hide_followers_count || account.user&.setting_hide_followers_count) ? nil : number_with_delimiter(account.followers_count) do + %span.counter-number= (Setting.hide_followers_count || account.user&.setting_hide_followers_count) ? '-' : (number_to_human account.followers_count, strip_insignificant_zeros: true) %span.counter-label= t('accounts.followers', count: account.followers_count) .spacer .public-account-header__tabs__tabs__buttons diff --git a/app/views/directories/index.html.haml b/app/views/directories/index.html.haml index 8d136a31f..0dc5e7d76 100644 --- a/app/views/directories/index.html.haml +++ b/app/views/directories/index.html.haml @@ -29,7 +29,7 @@ = number_to_human account.statuses_count, strip_insignificant_zeros: true %small= t('accounts.posts', count: account.statuses_count).downcase %td.accounts-table__count.optional - = Setting.hide_followers_count ? '-' : (number_to_human account.followers_count, strip_insignificant_zeros: true) + = (Setting.hide_followers_count || account.user&.setting_hide_followers_count) ? '-' : (number_to_human account.followers_count, strip_insignificant_zeros: true) %small= t('accounts.followers', count: account.followers_count).downcase %td.accounts-table__count - if account.last_status_at.present? diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index 53390b6d1..6510e0560 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -34,6 +34,10 @@ .fields-group = f.input :setting_hide_network, as: :boolean, wrapper: :with_label + - unless Setting.hide_followers_count + .fields-group + = f.input :setting_hide_followers_count, as: :boolean, wrapper: :with_label + %hr#settings_web/ .fields-group diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index ed6e6faa0..2976eee6e 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -79,6 +79,7 @@ en: setting_display_media_show_all: Show all setting_expand_spoilers: Always expand toots marked with content warnings setting_favourite_modal: Show confirmation dialog before favouriting (applies to Glitch flavour only) + setting_hide_followers_count: Hide your followers count setting_hide_network: Hide your network setting_noindex: Opt-out of search engine indexing setting_reduce_motion: Reduce motion in animations -- cgit From 3c033c4352f8b156887cd7157b4a89c23a545838 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 22 Dec 2018 20:02:09 +0100 Subject: Add moderation warnings (#9519) * Add moderation warnings Replace individual routes for disabling, silencing, and suspending a user, as well as the report update route, with a unified account action controller that allows you to select an action (none, disable, silence, suspend) as well as whether it should generate an e-mail notification with optional custom text. That notification, with the optional custom text, is saved as a warning. Additionally, there are warning presets you can configure to save time when performing the above. * Use Account#local_username_and_domain --- .../admin/account_actions_controller.rb | 36 ++++++ .../admin/account_moderation_notes_controller.rb | 1 + app/controllers/admin/accounts_controller.rb | 23 ++-- app/controllers/admin/reports_controller.rb | 79 ++++-------- app/controllers/admin/silences_controller.rb | 27 ----- app/controllers/admin/suspensions_controller.rb | 60 --------- .../admin/warning_presets_controller.rb | 58 +++++++++ app/helpers/admin/action_logs_helper.rb | 7 +- app/javascript/images/icon_flag.svg | 4 + app/javascript/images/mailer/icon_warning.png | Bin 0 -> 371 bytes app/javascript/styles/mailer.scss | 4 + app/javascript/styles/mastodon/admin.scss | 4 + app/mailers/user_mailer.rb | 12 ++ app/models/account.rb | 8 ++ app/models/account_warning.rb | 23 ++++ app/models/account_warning_preset.rb | 15 +++ app/models/admin/account_action.rb | 134 +++++++++++++++++++++ app/models/concerns/account_associations.rb | 2 + app/models/form/admin_suspension_confirmation.rb | 7 -- app/policies/account_policy.rb | 4 + app/policies/account_warning_preset_policy.rb | 19 +++ app/views/admin/account_actions/new.html.haml | 26 ++++ .../account_warnings/_account_warning.html.haml | 6 + app/views/admin/accounts/show.html.haml | 14 ++- app/views/admin/reports/show.html.haml | 17 +-- app/views/admin/suspensions/new.html.haml | 25 ---- app/views/admin/warning_presets/edit.html.haml | 11 ++ app/views/admin/warning_presets/index.html.haml | 30 +++++ app/views/user_mailer/warning.html.haml | 63 ++++++++++ app/views/user_mailer/warning.text.erb | 9 ++ app/views/user_mailer/welcome.text.erb | 2 +- config/locales/ar.yml | 5 - config/locales/ast.yml | 2 - config/locales/ca.yml | 6 - config/locales/co.yml | 6 - config/locales/cs.yml | 6 - config/locales/cy.yml | 6 - config/locales/da.yml | 6 - config/locales/de.yml | 6 - config/locales/el.yml | 6 - config/locales/en.yml | 32 ++++- config/locales/eo.yml | 5 - config/locales/es.yml | 6 - config/locales/eu.yml | 6 - config/locales/fa.yml | 6 - config/locales/fr.yml | 6 - config/locales/gl.yml | 6 - config/locales/it.yml | 6 - config/locales/ja.yml | 6 - config/locales/ko.yml | 6 - config/locales/nl.yml | 6 - config/locales/oc.yml | 6 - config/locales/pl.yml | 6 - config/locales/pt-BR.yml | 6 - config/locales/ru.yml | 6 - config/locales/simple_form.en.yml | 19 +++ config/locales/sk.yml | 6 - config/locales/sr.yml | 6 - config/routes.rb | 16 ++- .../20181213184704_create_account_warnings.rb | 12 ++ ...0181213185533_create_account_warning_presets.rb | 9 ++ db/schema.rb | 21 +++- spec/controllers/admin/accounts_controller_spec.rb | 52 -------- spec/controllers/admin/reports_controller_spec.rb | 84 ++++--------- spec/controllers/admin/silences_controller_spec.rb | 33 ----- .../admin/suspensions_controller_spec.rb | 39 ------ spec/fabricators/account_warning_fabricator.rb | 5 + .../account_warning_preset_fabricator.rb | 3 + spec/mailers/previews/user_mailer_preview.rb | 5 + spec/models/account_warning_preset_spec.rb | 5 + spec/models/account_warning_spec.rb | 5 + spec/models/admin/account_action_spec.rb | 4 + 72 files changed, 682 insertions(+), 536 deletions(-) create mode 100644 app/controllers/admin/account_actions_controller.rb delete mode 100644 app/controllers/admin/silences_controller.rb delete mode 100644 app/controllers/admin/suspensions_controller.rb create mode 100644 app/controllers/admin/warning_presets_controller.rb create mode 100644 app/javascript/images/icon_flag.svg create mode 100644 app/javascript/images/mailer/icon_warning.png create mode 100644 app/models/account_warning.rb create mode 100644 app/models/account_warning_preset.rb create mode 100644 app/models/admin/account_action.rb delete mode 100644 app/models/form/admin_suspension_confirmation.rb create mode 100644 app/policies/account_warning_preset_policy.rb create mode 100644 app/views/admin/account_actions/new.html.haml create mode 100644 app/views/admin/account_warnings/_account_warning.html.haml delete mode 100644 app/views/admin/suspensions/new.html.haml create mode 100644 app/views/admin/warning_presets/edit.html.haml create mode 100644 app/views/admin/warning_presets/index.html.haml create mode 100644 app/views/user_mailer/warning.html.haml create mode 100644 app/views/user_mailer/warning.text.erb create mode 100644 db/migrate/20181213184704_create_account_warnings.rb create mode 100644 db/migrate/20181213185533_create_account_warning_presets.rb delete mode 100644 spec/controllers/admin/silences_controller_spec.rb delete mode 100644 spec/controllers/admin/suspensions_controller_spec.rb create mode 100644 spec/fabricators/account_warning_fabricator.rb create mode 100644 spec/fabricators/account_warning_preset_fabricator.rb create mode 100644 spec/models/account_warning_preset_spec.rb create mode 100644 spec/models/account_warning_spec.rb create mode 100644 spec/models/admin/account_action_spec.rb (limited to 'app/models') diff --git a/app/controllers/admin/account_actions_controller.rb b/app/controllers/admin/account_actions_controller.rb new file mode 100644 index 000000000..e847495f1 --- /dev/null +++ b/app/controllers/admin/account_actions_controller.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Admin + class AccountActionsController < BaseController + before_action :set_account + + def new + @account_action = Admin::AccountAction.new(type: params[:type], report_id: params[:report_id], send_email_notification: true) + @warning_presets = AccountWarningPreset.all + end + + def create + account_action = Admin::AccountAction.new(resource_params) + account_action.target_account = @account + account_action.current_account = current_account + + account_action.save! + + if account_action.with_report? + redirect_to admin_report_path(account_action.report) + else + redirect_to admin_account_path(@account.id) + end + end + + private + + def set_account + @account = Account.find(params[:account_id]) + end + + def resource_params + params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification) + end + end +end diff --git a/app/controllers/admin/account_moderation_notes_controller.rb b/app/controllers/admin/account_moderation_notes_controller.rb index 7d5b9bf52..44f6e34f8 100644 --- a/app/controllers/admin/account_moderation_notes_controller.rb +++ b/app/controllers/admin/account_moderation_notes_controller.rb @@ -14,6 +14,7 @@ module Admin else @account = @account_moderation_note.target_account @moderation_notes = @account.targeted_moderation_notes.latest + @warnings = @account.targeted_account_warnings.latest.custom render template: 'admin/accounts/show' end diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb index 771302db8..10abd1e6a 100644 --- a/app/controllers/admin/accounts_controller.rb +++ b/app/controllers/admin/accounts_controller.rb @@ -2,9 +2,9 @@ module Admin class AccountsController < BaseController - before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :disable, :memorialize] + before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :remove_header, :enable, :memorialize] before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload] - before_action :require_local_account!, only: [:enable, :disable, :memorialize] + before_action :require_local_account!, only: [:enable, :memorialize] def index authorize :account, :index? @@ -13,8 +13,10 @@ module Admin def show authorize @account, :show? + @account_moderation_note = current_account.account_moderation_notes.new(target_account: @account) - @moderation_notes = @account.targeted_moderation_notes.latest + @moderation_notes = @account.targeted_moderation_notes.latest + @warnings = @account.targeted_account_warnings.latest.custom end def subscribe @@ -43,10 +45,17 @@ module Admin redirect_to admin_account_path(@account.id) end - def disable - authorize @account.user, :disable? - @account.user.disable! - log_action :disable, @account.user + def unsilence + authorize @account, :unsilence? + @account.unsilence! + log_action :unsilence, @account + redirect_to admin_account_path(@account.id) + end + + def unsuspend + authorize @account, :unsuspend? + @account.unsuspend! + log_action :unsuspend, @account redirect_to admin_account_path(@account.id) end diff --git a/app/controllers/admin/reports_controller.rb b/app/controllers/admin/reports_controller.rb index e97ddb9b6..f138376b2 100644 --- a/app/controllers/admin/reports_controller.rb +++ b/app/controllers/admin/reports_controller.rb @@ -13,75 +13,42 @@ module Admin authorize @report, :show? @report_note = @report.notes.new - @report_notes = (@report.notes.latest + @report.history).sort_by(&:created_at) + @report_notes = (@report.notes.latest + @report.history + @report.target_account.targeted_account_warnings.latest.custom).sort_by(&:created_at) @form = Form::StatusBatch.new end - def update + def assign_to_self authorize @report, :update? - process_report - - if @report.action_taken? - redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg') - else - redirect_to admin_report_path(@report) - end + @report.update!(assigned_account_id: current_account.id) + log_action :assigned_to_self, @report + redirect_to admin_report_path(@report) end - private - - def process_report - case params[:outcome].to_s - when 'assign_to_self' - @report.update!(assigned_account_id: current_account.id) - log_action :assigned_to_self, @report - when 'unassign' - @report.update!(assigned_account_id: nil) - log_action :unassigned, @report - when 'reopen' - @report.unresolve! - log_action :reopen, @report - when 'resolve' - @report.resolve!(current_account) - log_action :resolve, @report - when 'disable' - @report.resolve!(current_account) - @report.target_account.user.disable! - - log_action :resolve, @report - log_action :disable, @report.target_account.user - - resolve_all_target_account_reports - when 'silence' - @report.resolve!(current_account) - @report.target_account.update!(silenced: true) - - log_action :resolve, @report - log_action :silence, @report.target_account - - resolve_all_target_account_reports - else - raise ActiveRecord::RecordNotFound - end - - @report.reload + def unassign + authorize @report, :update? + @report.update!(assigned_account_id: nil) + log_action :unassigned, @report + redirect_to admin_report_path(@report) end - def resolve_all_target_account_reports - unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id) + def reopen + authorize @report, :update? + @report.unresolve! + log_action :reopen, @report + redirect_to admin_report_path(@report) end - def unresolved_reports_for_target_account - Report.where( - target_account: @report.target_account - ).unresolved + def resolve + authorize @report, :update? + @report.resolve!(current_account) + log_action :resolve, @report + redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg') end + private + def filtered_reports - ReportFilter.new(filter_params).results.order(id: :desc).includes( - :account, - :target_account - ) + ReportFilter.new(filter_params).results.order(id: :desc).includes(:account, :target_account) end def filter_params diff --git a/app/controllers/admin/silences_controller.rb b/app/controllers/admin/silences_controller.rb deleted file mode 100644 index 4c06a9c0c..000000000 --- a/app/controllers/admin/silences_controller.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module Admin - class SilencesController < BaseController - before_action :set_account - - def create - authorize @account, :silence? - @account.update!(silenced: true) - log_action :silence, @account - redirect_to admin_accounts_path - end - - def destroy - authorize @account, :unsilence? - @account.update!(silenced: false) - log_action :unsilence, @account - redirect_to admin_accounts_path - end - - private - - def set_account - @account = Account.find(params[:account_id]) - end - end -end diff --git a/app/controllers/admin/suspensions_controller.rb b/app/controllers/admin/suspensions_controller.rb deleted file mode 100644 index f9bbf36fb..000000000 --- a/app/controllers/admin/suspensions_controller.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -module Admin - class SuspensionsController < BaseController - before_action :set_account - - def new - @suspension = Form::AdminSuspensionConfirmation.new(report_id: params[:report_id]) - end - - def create - authorize @account, :suspend? - - @suspension = Form::AdminSuspensionConfirmation.new(suspension_params) - - if suspension_params[:acct] == @account.acct - resolve_report! if suspension_params[:report_id].present? - perform_suspend! - mark_reports_resolved! - redirect_to admin_accounts_path - else - flash.now[:alert] = I18n.t('admin.suspensions.bad_acct_msg') - render :new - end - end - - def destroy - authorize @account, :unsuspend? - @account.unsuspend! - log_action :unsuspend, @account - redirect_to admin_accounts_path - end - - private - - def set_account - @account = Account.find(params[:account_id]) - end - - def suspension_params - params.require(:form_admin_suspension_confirmation).permit(:acct, :report_id) - end - - def resolve_report! - report = Report.find(suspension_params[:report_id]) - report.resolve!(current_account) - log_action :resolve, report - end - - def perform_suspend! - @account.suspend! - Admin::SuspensionWorker.perform_async(@account.id) - log_action :suspend, @account - end - - def mark_reports_resolved! - Report.where(target_account: @account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id) - end - end -end diff --git a/app/controllers/admin/warning_presets_controller.rb b/app/controllers/admin/warning_presets_controller.rb new file mode 100644 index 000000000..37be842c5 --- /dev/null +++ b/app/controllers/admin/warning_presets_controller.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module Admin + class WarningPresetsController < BaseController + before_action :set_warning_preset, except: [:index, :create] + + def index + authorize :account_warning_preset, :index? + + @warning_presets = AccountWarningPreset.all + @warning_preset = AccountWarningPreset.new + end + + def create + authorize :account_warning_preset, :create? + + @warning_preset = AccountWarningPreset.new(warning_preset_params) + + if @warning_preset.save + redirect_to admin_warning_presets_path + else + @warning_presets = AccountWarningPreset.all + render :index + end + end + + def edit + authorize @warning_preset, :update? + end + + def update + authorize @warning_preset, :update? + + if @warning_preset.update(warning_preset_params) + redirect_to admin_warning_presets_path + else + render :edit + end + end + + def destroy + authorize @warning_preset, :destroy? + + @warning_preset.destroy! + redirect_to admin_warning_presets_path + end + + private + + def set_warning_preset + @warning_preset = AccountWarningPreset.find(params[:id]) + end + + def warning_preset_params + params.require(:account_warning_preset).permit(:text) + end + end +end diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index 68cf8c75d..359d60b60 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -23,6 +23,8 @@ module Admin::ActionLogsHelper link_to record.domain, "https://#{record.domain}" when 'Status' link_to record.account.acct, TagManager.instance.url_for(record) + when 'AccountWarning' + link_to record.target_account.acct, admin_account_path(record.target_account_id) end end @@ -34,6 +36,7 @@ module Admin::ActionLogsHelper link_to attributes['domain'], "https://#{attributes['domain']}" when 'Status' tmp_status = Status.new(attributes.except('reblogs_count', 'favourites_count')) + if tmp_status.account link_to tmp_status.account&.acct || "##{tmp_status.account_id}", admin_account_path(tmp_status.account_id) else @@ -81,6 +84,8 @@ module Admin::ActionLogsHelper 'envelope' when 'Status' 'pencil' + when 'AccountWarning' + 'warning' end end @@ -104,6 +109,6 @@ module Admin::ActionLogsHelper private def opposite_verbs?(log) - %w(DomainBlock EmailDomainBlock).include?(log.target_type) + %w(DomainBlock EmailDomainBlock AccountWarning).include?(log.target_type) end end diff --git a/app/javascript/images/icon_flag.svg b/app/javascript/images/icon_flag.svg new file mode 100644 index 000000000..3939c9d2b --- /dev/null +++ b/app/javascript/images/icon_flag.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/javascript/images/mailer/icon_warning.png b/app/javascript/images/mailer/icon_warning.png new file mode 100644 index 000000000..7baaac61c Binary files /dev/null and b/app/javascript/images/mailer/icon_warning.png differ diff --git a/app/javascript/styles/mailer.scss b/app/javascript/styles/mailer.scss index d83bd4d96..74d1df8ed 100644 --- a/app/javascript/styles/mailer.scss +++ b/app/javascript/styles/mailer.scss @@ -426,6 +426,10 @@ h5 { background: $success-green; } + &.alert-icon td { + background: $error-red; + } + img { max-width: 32px; width: 32px; diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index b6c771abf..e8f331932 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -542,6 +542,10 @@ a.name-tag, border-left-color: lighten($error-red, 12%); } + &.warning { + border-left-color: $gold-star; + } + &__bubble { padding: 16px; padding-left: 14px; diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index aa76b4dfe..8f3a4ab3a 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -78,4 +78,16 @@ class UserMailer < Devise::Mailer mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject') end end + + def warning(user, warning) + @resource = user + @warning = warning + @instance = Rails.configuration.x.local_domain + + I18n.with_locale(@resource.locale || I18n.default_locale) do + mail to: @resource.email, + subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}"), + reply_to: Setting.site_contact_email + end + end end diff --git a/app/models/account.rb b/app/models/account.rb index 5a7a9c580..16ef6c187 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -155,6 +155,14 @@ class Account < ApplicationRecord ResolveAccountService.new.call(acct) end + def silence! + update!(silenced: true) + end + + def unsilence! + update!(silenced: false) + end + def suspend! transaction do user&.disable! if local? diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb new file mode 100644 index 000000000..157e6c04d --- /dev/null +++ b/app/models/account_warning.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# == Schema Information +# +# Table name: account_warnings +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) +# target_account_id :bigint(8) +# action :integer default("none"), not null +# text :text default(""), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class AccountWarning < ApplicationRecord + enum action: %i(none disable silence suspend), _suffix: :action + + belongs_to :account, inverse_of: :account_warnings + belongs_to :target_account, class_name: 'Account', inverse_of: :targeted_account_warnings + + scope :latest, -> { order(created_at: :desc) } + scope :custom, -> { where.not(text: '') } +end diff --git a/app/models/account_warning_preset.rb b/app/models/account_warning_preset.rb new file mode 100644 index 000000000..ba8ceabb3 --- /dev/null +++ b/app/models/account_warning_preset.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: account_warning_presets +# +# id :bigint(8) not null, primary key +# text :text default(""), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class AccountWarningPreset < ApplicationRecord + validates :text, presence: true +end diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb new file mode 100644 index 000000000..84c3f880d --- /dev/null +++ b/app/models/admin/account_action.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +class Admin::AccountAction + include ActiveModel::Model + include AccountableConcern + include Authorization + + TYPES = %w( + none + disable + silence + suspend + ).freeze + + attr_accessor :target_account, + :current_account, + :type, + :text, + :report_id, + :warning_preset_id, + :send_email_notification + + attr_reader :warning + + def save! + ApplicationRecord.transaction do + process_action! + process_warning! + end + + queue_email! + process_reports! + end + + def report + @report ||= Report.find(report_id) if report_id.present? + end + + def with_report? + !report.nil? + end + + class << self + def types_for_account(account) + if account.local? + TYPES + else + TYPES - %w(none disable) + end + end + end + + private + + def process_action! + case type + when 'disable' + handle_disable! + when 'silence' + handle_silence! + when 'suspend' + handle_suspend! + end + end + + def process_warning! + return unless warnable? + + authorize(target_account, :warn?) + + @warning = AccountWarning.create!(target_account: target_account, + account: current_account, + action: type, + text: text_for_warning) + + # A log entry is only interesting if the warning contains + # custom text from someone. Otherwise it's just noise. + log_action(:create, warning) if warning.text.present? + end + + def process_reports! + return if report_id.blank? + + authorize(report, :update?) + + if type == 'none' + log_action(:resolve, report) + report.resolve!(current_account) + else + Report.where(target_account: target_account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id) + end + end + + def handle_disable! + authorize(target_account.user, :disable?) + log_action(:disable, target_account.user) + target_account.user&.disable! + end + + def handle_silence! + authorize(target_account, :silence?) + log_action(:silence, target_account) + target_account.silence! + end + + def handle_suspend! + authorize(target_account, :suspend?) + log_action(:suspend, target_account) + target_account.suspend! + queue_suspension_worker! + end + + def text_for_warning + [warning_preset&.text, text].compact.join("\n\n") + end + + def queue_suspension_worker! + Admin::SuspensionWorker.perform_async(target_account.id) + end + + def queue_email! + return unless warnable? + + UserMailer.warning(target_account.user, warning).deliver_later! + end + + def warnable? + send_email_notification && target_account.local? + end + + def warning_preset + @warning_preset ||= AccountWarningPreset.find(warning_preset_id) if warning_preset_id.present? + end +end diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb index ae50860ed..a894b5eed 100644 --- a/app/models/concerns/account_associations.rb +++ b/app/models/concerns/account_associations.rb @@ -39,6 +39,8 @@ module AccountAssociations # Moderation notes has_many :account_moderation_notes, dependent: :destroy, inverse_of: :account has_many :targeted_moderation_notes, class_name: 'AccountModerationNote', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account + has_many :account_warnings, dependent: :destroy, inverse_of: :account + has_many :targeted_account_warnings, class_name: 'AccountWarning', foreign_key: :target_account_id, dependent: :destroy, inverse_of: :target_account # Lists (that the account is on, not owned by the account) has_many :list_accounts, inverse_of: :account, dependent: :destroy diff --git a/app/models/form/admin_suspension_confirmation.rb b/app/models/form/admin_suspension_confirmation.rb deleted file mode 100644 index c34b5b30e..000000000 --- a/app/models/form/admin_suspension_confirmation.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class Form::AdminSuspensionConfirmation - include ActiveModel::Model - - attr_accessor :acct, :report_id -end diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb index 07bae68ef..9c145979d 100644 --- a/app/policies/account_policy.rb +++ b/app/policies/account_policy.rb @@ -9,6 +9,10 @@ class AccountPolicy < ApplicationPolicy staff? end + def warn? + staff? && !record.user&.staff? + end + def suspend? staff? && !record.user&.staff? end diff --git a/app/policies/account_warning_preset_policy.rb b/app/policies/account_warning_preset_policy.rb new file mode 100644 index 000000000..bccbd33ef --- /dev/null +++ b/app/policies/account_warning_preset_policy.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class AccountWarningPresetPolicy < ApplicationPolicy + def index? + staff? + end + + def create? + staff? + end + + def update? + staff? + end + + def destroy? + staff? + end +end diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml new file mode 100644 index 000000000..97286c8e5 --- /dev/null +++ b/app/views/admin/account_actions/new.html.haml @@ -0,0 +1,26 @@ +- content_for :page_title do + = t('admin.account_actions.title', acct: @account.acct) + += simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f| + = f.input :report_id, as: :hidden + + .fields-group + = f.input :type, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { I18n.t("simple_form.labels.admin_account_action.types.#{type}")}, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.acct) + + - if @account.local? + %hr.spacer/ + + .fields-group + = f.input :send_email_notification, as: :boolean, wrapper: :with_label + + %hr.spacer/ + + - unless @warning_presets.empty? + .fields-group + = f.input :warning_preset_id, collection: @warning_presets, label_method: :text, wrapper: :with_block_label + + .fields-group + = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path) + + .actions + = f.button :button, t('admin.account_actions.action'), type: :submit diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml new file mode 100644 index 000000000..8c9c9679c --- /dev/null +++ b/app/views/admin/account_warnings/_account_warning.html.haml @@ -0,0 +1,6 @@ +.speech-bubble.warning + .speech-bubble__bubble + = Formatter.instance.linkify(account_warning.text) + .speech-bubble__owner + = admin_account_link_to account_warning.account + %time.formatted{ datetime: account_warning.created_at.iso8601 }= l account_warning.created_at diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index e9f765107..226aef732 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -64,7 +64,7 @@ = table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post if can?(:enable, @account.user) - else = t('admin.accounts.enabled') - = table_link_to 'lock', t('admin.accounts.disable'), disable_admin_account_path(@account.id), method: :post if can?(:disable, @account.user) + = table_link_to 'lock', t('admin.accounts.disable'), new_admin_account_action_path(@account.id, type: 'disable') if can?(:disable, @account.user) %tr %th= t('admin.accounts.most_recent_ip') %td= @account.user_current_sign_in_ip @@ -119,18 +119,18 @@ %div{ style: 'float: left' } - if @account.silenced? - = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button' if can?(:unsilence, @account) + = link_to t('admin.accounts.undo_silenced'), unsilence_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsilence, @account) - else - = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button button--destructive' if can?(:silence, @account) + = link_to t('admin.accounts.silence'), new_admin_account_action_path(@account.id, type: 'silence'), class: 'button button--destructive' if can?(:silence, @account) - if @account.local? - unless @account.user_confirmed? = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user) - if @account.suspended? - = link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button' if can?(:unsuspend, @account) + = link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(@account.id), method: :post, class: 'button' if can?(:unsuspend, @account) - else - = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_suspension_path(@account.id), class: 'button button--destructive' if can?(:suspend, @account) + = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@account.id, type: 'suspend'), class: 'button button--destructive' if can?(:suspend, @account) - if !@account.local? && @account.hub_url.present? %hr.spacer/ @@ -184,6 +184,10 @@ %hr.spacer/ += render @warnings + +%hr.spacer/ + = render @moderation_notes = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f| diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 3588d151d..863dada9e 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -8,13 +8,14 @@ - if @report.unresolved? %div{ style: 'float: right' } - if @report.target_account.local? - = link_to t('admin.accounts.disable'), admin_report_path(@report, outcome: 'disable'), method: :put, class: 'button button--destructive' - = link_to t('admin.accounts.silence'), admin_report_path(@report, outcome: 'silence'), method: :put, class: 'button button--destructive' - = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_suspension_path(@report.target_account_id, report_id: @report.id), class: 'button button--destructive' + = link_to t('admin.accounts.warn'), new_admin_account_action_path(@report.target_account_id, type: 'none', report_id: @report.id), class: 'button' + = link_to t('admin.accounts.disable'), new_admin_account_action_path(@report.target_account_id, type: 'disable', report_id: @report.id), class: 'button button--destructive' + = link_to t('admin.accounts.silence'), new_admin_account_action_path(@report.target_account_id, type: 'silence', report_id: @report.id), class: 'button button--destructive' + = link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(@report.target_account_id, type: 'suspend', report_id: @report.id), class: 'button button--destructive' %div{ style: 'float: left' } - = link_to t('admin.reports.mark_as_resolved'), admin_report_path(@report, outcome: 'resolve'), method: :put, class: 'button' + = link_to t('admin.reports.mark_as_resolved'), resolve_admin_report_path(@report), method: :post, class: 'button' - else - = link_to t('admin.reports.mark_as_unresolved'), admin_report_path(@report, outcome: 'reopen'), method: :put, class: 'button' + = link_to t('admin.reports.mark_as_unresolved'), reopen_admin_report_path(@report), method: :post, class: 'button' %hr.spacer @@ -67,10 +68,10 @@ = admin_account_link_to @report.assigned_account %td - if @report.assigned_account != current_user.account - = table_link_to 'user', t('admin.reports.assign_to_self'), admin_report_path(@report, outcome: 'assign_to_self'), method: :put + = table_link_to 'user', t('admin.reports.assign_to_self'), assign_to_self_admin_report_path(@report), method: :post %td - if !@report.assigned_account.nil? - = table_link_to 'trash', t('admin.reports.unassign'), admin_report_path(@report, outcome: 'unassign'), method: :put + = table_link_to 'trash', t('admin.reports.unassign'), unassign_admin_report_path(@report), method: :post %hr.spacer @@ -104,7 +105,7 @@ - @report_notes.each do |item| - if item.is_a?(Admin::ActionLog) = render partial: 'action_log', locals: { action_log: item } - - elsif item.is_a?(ReportNote) + - else = render item = simple_form_for @report_note, url: admin_report_notes_path do |f| diff --git a/app/views/admin/suspensions/new.html.haml b/app/views/admin/suspensions/new.html.haml deleted file mode 100644 index f03ecacc3..000000000 --- a/app/views/admin/suspensions/new.html.haml +++ /dev/null @@ -1,25 +0,0 @@ -- content_for :page_title do - = t('admin.suspensions.title', acct: @account.acct) - -= simple_form_for @suspension, url: admin_account_suspension_path(@account.id), method: :post do |f| - %p.hint= t('admin.suspensions.warning_html') - - .fields-group - %ul - %li.negative-hint - = number_to_human @account.statuses_count, strip_insignificant_zeros: true - = t('accounts.posts', count: @account.statuses_count) - %li.negative-hint - = number_to_human @account.following_count, strip_insignificant_zeros: true - = t('accounts.following', count: @account.following_count) - %li.negative-hint - = number_to_human @account.followers_count, strip_insignificant_zeros: true - = t('accounts.followers', count: @account.followers_count) - - %p.hint= t('admin.suspensions.hint_html', value: content_tag(:code, @account.acct)) - - = f.input :acct - = f.input_field :report_id, as: :hidden - - .actions - = f.button :button, t('admin.suspensions.proceed'), type: :submit, class: 'negative' diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml new file mode 100644 index 000000000..9522746cd --- /dev/null +++ b/app/views/admin/warning_presets/edit.html.haml @@ -0,0 +1,11 @@ +- content_for :page_title do + = t('admin.warning_presets.edit_preset') + += simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |f| + = render 'shared/error_messages', object: @warning_preset + + .fields-group + = f.input :text, wrapper: :with_block_label + + .actions + = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml new file mode 100644 index 000000000..45913ef73 --- /dev/null +++ b/app/views/admin/warning_presets/index.html.haml @@ -0,0 +1,30 @@ +- content_for :page_title do + = t('admin.warning_presets.title') + +- if can? :create, :account_warning_preset + = simple_form_for @warning_preset, url: admin_warning_presets_path do |f| + = render 'shared/error_messages', object: @warning_preset + + .fields-group + = f.input :text, wrapper: :with_block_label + + .actions + = f.button :button, t('admin.warning_presets.add_new'), type: :submit + + %hr.spacer/ + +- unless @warning_presets.empty? + .table-wrapper + %table.table + %thead + %tr + %th= t('simple_form.labels.account_warning_preset.text') + %th + %tbody + - @warning_presets.each do |preset| + %tr + %td + = Formatter.instance.linkify(preset.text) + %td + = table_link_to 'pencil', t('admin.warning_presets.edit'), edit_admin_warning_preset_path(preset) + = table_link_to 'trash', t('admin.warning_presets.delete'), admin_warning_preset_path(preset), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml new file mode 100644 index 000000000..c5e1f5a28 --- /dev/null +++ b/app/views/user_mailer/warning.html.haml @@ -0,0 +1,63 @@ +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.hero + .email-row + .col-6 + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.text-center.padded + %table.hero-icon.alert-icon{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td + = image_tag full_pack_url('icon_warning.png'), alt: '' + + %h1= t "user_mailer.warning.title.#{@warning.action}" + +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.content-start + .email-row + .col-6 + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.text-center + - unless @warning.none_action? + %p= t "user_mailer.warning.explanation.#{@warning.action}" + + - unless @warning.text.blank? + = Formatter.instance.linkify(@warning.text) + +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.button-cell + %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.button-primary + = link_to about_more_url do + %span= t 'user_mailer.warning.review_server_policies' diff --git a/app/views/user_mailer/warning.text.erb b/app/views/user_mailer/warning.text.erb new file mode 100644 index 000000000..b4f2402cb --- /dev/null +++ b/app/views/user_mailer/warning.text.erb @@ -0,0 +1,9 @@ +<%= t "user_mailer.warning.title.#{@warning.action}" %> + +=== + +<% unless @warning.none_action? %> +<%= t "user_mailer.warning.explanation.#{@warning.action}" %> + +<% end %> +<%= @warning.text %> diff --git a/app/views/user_mailer/welcome.text.erb b/app/views/user_mailer/welcome.text.erb index 5bd0cab2a..845458c32 100644 --- a/app/views/user_mailer/welcome.text.erb +++ b/app/views/user_mailer/welcome.text.erb @@ -2,7 +2,7 @@ === -<%= t 'user_mailer.welcome.full_handle' %> (<%= "@#{@resource.account.username}@#{@instance}" %>) +<%= t 'user_mailer.welcome.full_handle' %> (<%= "@#{@resource.account.local_username_and_domain}" %>) <%= t 'user_mailer.welcome.full_handle_hint', instance: @instance %> --- diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 2fa075273..0652089d4 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -455,11 +455,6 @@ ar: last_delivery: آخر إيداع title: WebSub topic: الموضوع - suspensions: - bad_acct_msg: قيمة التأكيد غير متطابقة. متأكد مِن أنك بصدد تعليق الحساب الصحيح؟ - hint_html: 'لتأكيد إجراء تعليق الحساب، يُرجى إدخال %{value} في الحقل التالي:' - proceed: مواصلة - title: تعليق الحساب %{acct} tags: accounts: الحسابات hidden: المخفية diff --git a/config/locales/ast.yml b/config/locales/ast.yml index e6c51b10e..c18c398eb 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -121,8 +121,6 @@ ast: failed_to_execute: Fallu al executar subscriptions: title: WebSub - suspensions: - warning_html: 'El suspender esta cuenta va desaniciar de mou irreversible los sos datos qu''inclúin:' title: Alministración admin_mailer: new_report: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 1575b32ea..b7e3cb7f6 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -439,12 +439,6 @@ ca: last_delivery: Últim lliurament title: WebSub topic: Tema - suspensions: - bad_acct_msg: El valor de confirmació no s'ha trobat. Estàs suspenen el compte correcte? - hint_html: 'Per confirmar la suspensió del compte, introdueix %{value} al camp següent:' - proceed: Procedeix - title: Suspèn %{acct} - warning_html: 'Suspenen aquest compte esborrarà irreversiblement les dades del compte, incloent:' tags: accounts: Comptes hidden: Amagat diff --git a/config/locales/co.yml b/config/locales/co.yml index c15f241c6..3df78f007 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -439,12 +439,6 @@ co: last_delivery: Ultima arricata title: WebSub topic: Sughjettu - suspensions: - bad_acct_msg: U valore di cunfirmazione ùn era micca curretta. Site sicuru·a di suspende u bonu contu? - hint_html: 'Per cunfirmà a suspensione di u contu, entrate %{value} quì sottu:' - proceed: Cuntinuà - title: Suspende %{acct} - warning_html: 'A suspensione di u contu sguasserà di manera irreversibile i so dati, cum''è:' tags: accounts: Conti hidden: Piattatu diff --git a/config/locales/cs.yml b/config/locales/cs.yml index d25ca6c2c..0042d5641 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -444,12 +444,6 @@ cs: last_delivery: Poslední doručení title: WebSub topic: Téma - suspensions: - bad_acct_msg: Hodnota pro potvrzení neodpovídá. Suspendujete správný účet? - hint_html: 'Pro potvrzení suspenzace účtu prosím zadejte do pole níže %{value}:' - proceed: Pokračovat - title: Suspendovat účet %{acct} - warning_html: 'Suspenzace tohoto účtu nenávratně smaže z tohoto účtu data, včetně:' tags: accounts: Účty hidden: Skryté diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 24ae6fa10..2467d3e78 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -423,12 +423,6 @@ cy: last_delivery: Danfoniad diwethaf title: WebSub topic: Pwnc - suspensions: - bad_acct_msg: Nid yw'r gwerthoedd cadarnhau yn cyfateb. Ydych chi'n atal y cyfrif cywir? - hint_html: 'I gadarnhau atal y cyfrif, mewnbynwch %{value} yn y maes isod:' - proceed: Parhau - title: Atal %{acct} - warning_html: 'Mi fydd atal y cyfrif hwn yn dileu data am byth o''r cyfrif hwn, gan gynnwys:' title: Gweinyddiaeth admin_mailer: new_report: diff --git a/config/locales/da.yml b/config/locales/da.yml index c6bdc753a..202f6bfb3 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -427,12 +427,6 @@ da: last_delivery: Sidste levering title: Websub topic: Emne - suspensions: - bad_acct_msg: Bekræftelsværdien stemte ikke overens. Er du ved at udelukke den rigtige konto? - hint_html: 'For at bekræfte udelukkelsen af kontoen, indtast venligst %{value} i nedenstående felt:' - proceed: Fortsæt - title: Udeluk %{acct} - warning_html: 'Udelukkelse af denne konto vil uigenkaldeligt slette al data fra denne konto, hvilket indebærer:' title: Administration admin_mailer: new_report: diff --git a/config/locales/de.yml b/config/locales/de.yml index 945d5a0ff..647897171 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -439,12 +439,6 @@ de: last_delivery: Letzte Zustellung title: WebSub topic: Thema - suspensions: - bad_acct_msg: Der Bestätigungswert stimmt nicht überein. Sperrst du das richtige Benutzerkonto? - hint_html: 'Um die Sperrung des Benutzerkontos zu genehmigen tippe %{value} in das Feld unten ein:' - proceed: Fortfahren - title: "%{acct} sperren" - warning_html: 'Die Sperrung des Benutzerkontos wird unwiederrufliche Schäden hervorrufen und alle Daten löschen, die folgendes beinhalten:' tags: accounts: Konten hidden: Versteckt diff --git a/config/locales/el.yml b/config/locales/el.yml index 66393f213..e03a116d0 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -439,12 +439,6 @@ el: last_delivery: Τελευταία παράδοση title: WebSub topic: Θέμα - suspensions: - bad_acct_msg: Η τιμή επιβεβαίωσης δεν ταιριάζει. Σίγουρα αναστέλλεις το σωστό λογαριασμό; - hint_html: 'Για να επιβεβαιώσεις την αναστολή του λογαριασμού, γράψε %{value} στο ακόλουθο πεδίο:' - proceed: Συνέχεια - title: Αναστολή %{acct} - warning_html: 'Αναστέλλοντας αυτό το λογαριασμό θα διαγραφούν αμετάκλητα δεδομένα του, μεταξύ των οποίων:' tags: accounts: Λογαριασμοί hidden: Κρυμμένες diff --git a/config/locales/en.yml b/config/locales/en.yml index bd0b0c3d5..bea182f0b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -70,6 +70,9 @@ en: moderator: Mod unfollow: Unfollow admin: + account_actions: + action: Perform action + title: Perform moderation action on %{acct} account_moderation_notes: create: Leave note created_msg: Moderation note successfully created! @@ -173,6 +176,7 @@ en: assigned_to_self_report: "%{name} assigned report %{target} to themselves" change_email_user: "%{name} changed the e-mail address of user %{target}" confirm_user: "%{name} confirmed e-mail address of user %{target}" + create_account_warning: "%{name} sent a warning to %{target}" create_custom_emoji: "%{name} uploaded new emoji %{target}" create_domain_block: "%{name} blocked domain %{target}" create_email_domain_block: "%{name} blacklisted e-mail domain %{target}" @@ -441,12 +445,6 @@ en: last_delivery: Last delivery title: WebSub topic: Topic - suspensions: - bad_acct_msg: The confirmation value didn't match up. Are you suspending the right account? - hint_html: 'To confirm the suspension of the account, please enter %{value} into the field below:' - proceed: Proceed - title: Suspend %{acct} - warning_html: 'Suspending this account will irreversibly delete data from this account, which includes:' tags: accounts: Accounts hidden: Hidden @@ -456,6 +454,12 @@ en: unhide: Show in directory visible: Visible title: Administration + warning_presets: + add_new: Add new + delete: Delete + edit: Edit + edit_preset: Edit warning preset + title: Manage warning presets admin_mailer: new_report: body: "%{reporter} has reported %{target}" @@ -922,6 +926,22 @@ en: explanation: You requested a full backup of your Mastodon account. It's now ready for download! subject: Your archive is ready for download title: Archive takeout + warning: + explanation: + disable: While your account is frozen, your account data remains intact, but you cannot perform any actions until it is unlocked. + silence: While your account is limited, only people who are already following you will see your toots on this server, and you may be excluded from various public listings. However, others may still manually follow you. + suspend: Your account has been suspended, and all of your toots and your uploaded media files have been irreversibly removed from this server, and servers where you had followers. + review_server_policies: Review server policies + subject: + disable: Your account %{acct} has been frozen + none: Warning for %{acct} + silence: Your account %{acct} has been limited + suspend: Your account %{acct} has been suspended + title: + disable: Account frozen + none: Warning + silence: Account limited + suspend: Account suspended welcome: edit_profile_action: Setup profile edit_profile_step: You can customize your profile by uploading an avatar, header, changing your display name and more. If you’d like to review new followers before they’re allowed to follow you, you can lock your account. diff --git a/config/locales/eo.yml b/config/locales/eo.yml index f944b2a19..6a62f7021 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -427,11 +427,6 @@ eo: last_delivery: Lasta livero title: WebSub topic: Temo - suspensions: - hint_html: 'Por konformi la haltigo de la konto, bonvolu enigi %{value} en la kampo sube:' - proceed: Daŭrigita - title: Haltigi %{acct} - warning_html: 'Haltigi ĉi tiu konton forigos senrevene datumojn de ĉi tiu konto, inklusive de:' title: Administrado admin_mailer: new_report: diff --git a/config/locales/es.yml b/config/locales/es.yml index 4cd1e2a38..8927c3b38 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -433,12 +433,6 @@ es: last_delivery: Última entrega title: WebSub topic: Tópico - suspensions: - bad_acct_msg: El valor de confirmación no cuadra. ¿Estás suspendiendo la cuenta correcta? - hint_html: 'Para confirmar las suspensión de la cuenta, por favor introduce %{value} en el campo de abajo:' - proceed: Proceder - title: Suspender %{acct} - warning_html: 'Suspender esta cuenta borrará irreversiblemente los datos de stra cuenta que incluyen:' title: Administración admin_mailer: new_report: diff --git a/config/locales/eu.yml b/config/locales/eu.yml index c96438bc3..eb148c6a2 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -435,12 +435,6 @@ eu: last_delivery: Azken bidalketa title: WebSub topic: Mintzagaia - suspensions: - bad_acct_msg: Berrespen balioa ez dator bat. Dagokion kontua kanporatzen ari zara? - hint_html: 'Kontuaren kanporatzea berresteko, sartu %{value} beheko eremuan:' - proceed: Jarraitu - title: Kanporatu %{acct} - warning_html: 'Kontu hau kanporatzeak behin betiko ezabatuko ditu kontu honetako datuak, hauek barne:' tags: accounts: Kontuak hidden: Ezkutatuta diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 7802ca98d..a87949183 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -433,12 +433,6 @@ fa: last_delivery: آخرین ارسال title: WebSub topic: موضوع - suspensions: - bad_acct_msg: محتوایی که برای تأیید وارد کردید منطبق نبود. آیا دارید حساب درستی را معلق می‌کنید؟ - hint_html: 'برای تأیید معلق‌کردن حساب، لطفاً در کادر زیر %{value} را وارد کنید:' - proceed: ادامه - title: معلق‌کردن %{acct} - warning_html: 'معلق‌کردن این حساب برای همیشه داده‌هایش را پاک می‌کند. داده‌هایی شامل:' title: مدیریت سرور admin_mailer: new_report: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 3d33cd40c..167c942ee 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -439,12 +439,6 @@ fr: last_delivery: Dernière livraison title: WebSub topic: Sujet - suspensions: - bad_acct_msg: La valeur de confirmation n'a pas correspondu. Êtes-vous certain de suspendre le bon compte ? - hint_html: 'Pour confirmer la suspension du compte, veuillez entrer %{value} dans le champ ci-dessous :' - proceed: Confirmer - title: Suspension de %{acct} - warning_html: 'Suspendre ce compte effacera irréversiblement les données de ce compte, ce qui inclut :' tags: accounts: Comptes hidden: Masqué diff --git a/config/locales/gl.yml b/config/locales/gl.yml index de1557fb9..b6830fb72 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -439,12 +439,6 @@ gl: last_delivery: Última entrega title: WebSub topic: Asunto - suspensions: - bad_acct_msg: O valor de confirmación non é coincidente. Está a suspender a conta correcta? - hint_html: 'Para confirmar a suspensión da conta introduza %{value} no campo inferior:' - proceed: Proceder - title: Suspender %{acct} - warning_html: 'Ao suspender esta conta eliminará de xeito irreversible os datos de esta conta, que inclúe:' tags: accounts: Contas hidden: Ocultas diff --git a/config/locales/it.yml b/config/locales/it.yml index dc62b1bea..e9bf78cdf 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -429,12 +429,6 @@ it: confirmed: Confermato expires_in: Scade in topic: Argomento - suspensions: - bad_acct_msg: Il valore di conferma non corrisponde. Stai sospendendo l'account giusto? - hint_html: 'Per confermare la sospensione dell''account, inserisci %{value} nel campo qui sotto:' - proceed: Continua - title: Sospendi %{acct} - warning_html: 'La sospensione dell''account comporta la cancellazione irreversibile dei suoi dati, che comprendono:' title: Amministrazione application_mailer: notification_preferences: Cambia preferenze email diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 038131a61..292acf52f 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -441,12 +441,6 @@ ja: last_delivery: 最終配送 title: WebSub topic: トピック - suspensions: - bad_acct_msg: 値が一致しませんでした。停止しようとしているアカウントに間違いはありませんか? - hint_html: 'アカウントの停止を確認するには、以下のフィールドに %{value} と入力してください:' - proceed: 完全に活動停止させる - title: "%{acct} を停止" - warning_html: 'このアカウントを停止すると、このアカウントから次のようなデータが不可逆的に削除されます:' tags: accounts: アカウント hidden: 非表示 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 40dab2d79..6bbc71e0b 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -441,12 +441,6 @@ ko: last_delivery: 최종 발송 title: WebSub topic: 토픽 - suspensions: - bad_acct_msg: 확인값이 일치하지 않습니다. 정지하려는 계정이 맞습니까? - hint_html: '이 계정을 정지하려면 %{value}를 아래 입력칸에 입력하세요:' - proceed: 완전히 정지시키기 - title: "%{acct} 정지하기" - warning_html: '이 계정을 정지하면 계정의 데이터를 모두 삭제하며 되돌릴 수 없습니다. 이것은 다음을 포함합니다:' tags: accounts: 계정들 hidden: 숨겨짐 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index d0578bc74..700217830 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -439,12 +439,6 @@ nl: last_delivery: Laatste bezorging title: WebSub topic: Account - suspensions: - bad_acct_msg: De bevestigingswaarde kwam niet overeen. Schort je wel het juiste account op? - hint_html: Vul in het veld hieronder %{value} in, om het opschorten van dit account te bevestigen. - proceed: Ga verder - title: "%{acct} opschorten" - warning_html: 'Door het opschorten van dit account worden gegevens van dit account permanent verwijderd, waaronder:' tags: accounts: Accounts hidden: Verborgen diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 0468fac86..e647e400c 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -439,12 +439,6 @@ oc: last_delivery: Darrièra distribucion title: WebSub topic: Subjècte - suspensions: - bad_acct_msg: La valor de confirmacion a pas coïncidit. Sètz a suspendre lo bon compte ? - hint_html: 'Per confirmar la suspension del compte, picatz %{value} al camp çai-jos :' - proceed: Tractat - title: Suspension de %{acct} - warning_html: 'Suspendre aqueste compte suprimirà irreversiblament las donadas del compte, aquò compren :' tags: accounts: Comptes hidden: Amagat diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 79ba6f9fb..7fd5df038 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -445,12 +445,6 @@ pl: last_delivery: Ostatnio doręczono title: WebSub topic: Temat - suspensions: - bad_acct_msg: Zawartość potwierdzenia nie zgadza się. Czy próbujesz zawiesić właściwe konto? - hint_html: 'Aby potwierdzić zawieszenie konta, wprowadź %{value} w poniższe pole:' - proceed: Przejdź - title: Zawieś %{acct} - warning_html: 'Zawieszenie konta będzie skutkowało nieodwracalnym usunięciem danych z tego konta, wliczając:' tags: accounts: Konta hidden: Ukryte diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 27f3b820c..e9625628b 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -439,12 +439,6 @@ pt-BR: last_delivery: Última entrega title: WebSub topic: Tópico - suspensions: - bad_acct_msg: Os valores de confirmação não correspondem. Você está suspendendo a conta certa? - hint_html: 'Para confirmar a suspensão da conta, por favor digite %{value} no campo abaixo:' - proceed: Prosseguir - title: Suspender %{acct} - warning_html: 'Suspender essa conta vai remover irreversivelmente dados dessa conta, o que inclui:' tags: accounts: Contas hidden: Escondido diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 9fa85b7c2..dceb41376 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -427,12 +427,6 @@ ru: last_delivery: Последняя доставка title: WebSub topic: Тема - suspensions: - bad_acct_msg: Не удалось найти такое число подтверждения. Вы уверены, что замораживаете нужный аккаунт? - hint_html: 'Чтобы подтвердить заморозку аккаунта, пожалуйста, введите %{value} в поле ниже:' - proceed: Продолжить - title: Заморозить %{acct} - warning_html: 'Заморозка этого аккаунта приведёт к необратимому удалению данных с этого аккаунта, включая:' title: Администрирование admin_mailer: new_report: diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index ce6a62e87..4363c59e4 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -2,6 +2,13 @@ en: simple_form: hints: + account_warning_preset: + text: You can use toot syntax, such as URLs, hashtags and mentions + admin_account_action: + send_email_notification: The user will receive an explanation of what happened with their account + text_html: Optional. You can use toot syntax. You can add warning presets to save time + type_html: Choose what to do with %{acct} + warning_preset_id: Optional. You can still add custom text to end of the preset defaults: autofollow: People who sign up through the invite will automatically follow you avatar: PNG, GIF or JPG. At most %{size}. Will be downscaled to %{dimensions}px @@ -40,6 +47,18 @@ en: fields: name: Label value: Content + account_warning_preset: + text: Preset text + admin_account_action: + send_email_notification: Notify the user per e-mail + text: Custom warning + type: Action + types: + disable: Disable + none: Do nothing + silence: Silence + suspend: Suspend and irreversibly delete account data + warning_preset_id: Use a warning preset defaults: autofollow: Invite to follow your account avatar: Avatar diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 3458c699c..f44d971a4 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -444,12 +444,6 @@ sk: last_delivery: Posledné doručenie title: WebSub topic: Téma - suspensions: - bad_acct_msg: Hodnota pre potvrdenie sa nezhoduje. Si si istý/á že zamrazuješ ten správny účet? - hint_html: 'Pre potvrdenie zamrazenia účtu, prosím napíš %{value} do následujúceho políčka:' - proceed: Pokračuj - title: Zamraziť %{acct} - warning_html: 'Zamrazením tohto účtu budú dáta na tomto účte nenávratne zmazané, zahŕňajúc:' tags: accounts: Účty hidden: Skryté diff --git a/config/locales/sr.yml b/config/locales/sr.yml index da621a910..8dee9fdac 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -443,12 +443,6 @@ sr: last_delivery: Последња достава title: WebSub topic: Topic - suspensions: - bad_acct_msg: Вредност потврде се не поклапа. Да ли суспендујете прави рачун? - hint_html: 'Да бисте потврдили суспензију налога, унесите %{value} у поље испод:' - proceed: Настави - title: Суспендуј %{acct} - warning_html: 'Суспендовање овог налога ће неповратноизбрисати све податке са овог налога, који укључују:' title: Администрација admin_mailer: new_report: diff --git a/config/routes.rb b/config/routes.rb index 0aba433e2..7723a08af 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -139,6 +139,7 @@ Rails.application.routes.draw do resources :domain_blocks, only: [:index, :new, :create, :show, :destroy] resources :email_domain_blocks, only: [:index, :new, :create, :destroy] resources :action_logs, only: [:index] + resources :warning_presets, except: [:new] resource :settings, only: [:edit, :update] resources :invites, only: [:index, :create, :destroy] do @@ -160,7 +161,14 @@ Rails.application.routes.draw do end end - resources :reports, only: [:index, :show, :update] do + resources :reports, only: [:index, :show] do + member do + post :assign_to_self + post :unassign + post :reopen + post :resolve + end + resources :reported_statuses, only: [:create] end @@ -171,7 +179,8 @@ Rails.application.routes.draw do post :subscribe post :unsubscribe post :enable - post :disable + post :unsilence + post :unsuspend post :redownload post :remove_avatar post :remove_header @@ -180,8 +189,7 @@ Rails.application.routes.draw do resource :change_email, only: [:show, :update] resource :reset, only: [:create] - resource :silence, only: [:create, :destroy] - resource :suspension, only: [:new, :create, :destroy] + resource :action, only: [:new, :create], controller: 'account_actions' resources :statuses, only: [:index, :create, :update, :destroy] resource :confirmation, only: [:create] do diff --git a/db/migrate/20181213184704_create_account_warnings.rb b/db/migrate/20181213184704_create_account_warnings.rb new file mode 100644 index 000000000..e768be277 --- /dev/null +++ b/db/migrate/20181213184704_create_account_warnings.rb @@ -0,0 +1,12 @@ +class CreateAccountWarnings < ActiveRecord::Migration[5.2] + def change + create_table :account_warnings do |t| + t.belongs_to :account, foreign_key: { on_delete: :nullify } + t.belongs_to :target_account, foreign_key: { to_table: 'accounts', on_delete: :cascade } + t.integer :action, null: false, default: 0 + t.text :text, null: false, default: '' + + t.timestamps + end + end +end diff --git a/db/migrate/20181213185533_create_account_warning_presets.rb b/db/migrate/20181213185533_create_account_warning_presets.rb new file mode 100644 index 000000000..9c81f1b5e --- /dev/null +++ b/db/migrate/20181213185533_create_account_warning_presets.rb @@ -0,0 +1,9 @@ +class CreateAccountWarningPresets < ActiveRecord::Migration[5.2] + def change + create_table :account_warning_presets do |t| + t.text :text, null: false, default: '' + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 51ac43e1d..51a7b5e74 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_12_07_011115) do +ActiveRecord::Schema.define(version: 2018_12_13_185533) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -76,6 +76,23 @@ ActiveRecord::Schema.define(version: 2018_12_07_011115) do t.index ["tag_id"], name: "index_account_tag_stats_on_tag_id", unique: true end + create_table "account_warning_presets", force: :cascade do |t| + t.text "text", default: "", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "account_warnings", force: :cascade do |t| + t.bigint "account_id" + t.bigint "target_account_id" + t.integer "action", default: 0, null: false + t.text "text", default: "", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["account_id"], name: "index_account_warnings_on_account_id" + t.index ["target_account_id"], name: "index_account_warnings_on_target_account_id" + end + create_table "accounts", force: :cascade do |t| t.string "username", default: "", null: false t.string "domain" @@ -656,6 +673,8 @@ ActiveRecord::Schema.define(version: 2018_12_07_011115) do add_foreign_key "account_pins", "accounts", on_delete: :cascade add_foreign_key "account_stats", "accounts", on_delete: :cascade add_foreign_key "account_tag_stats", "tags", on_delete: :cascade + add_foreign_key "account_warnings", "accounts", column: "target_account_id", on_delete: :cascade + add_foreign_key "account_warnings", "accounts", on_delete: :nullify add_foreign_key "accounts", "accounts", column: "moved_to_account_id", on_delete: :nullify add_foreign_key "admin_action_logs", "accounts", on_delete: :cascade add_foreign_key "backups", "users", on_delete: :nullify diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb index dbcad3c2d..a348ab3d7 100644 --- a/spec/controllers/admin/accounts_controller_spec.rb +++ b/spec/controllers/admin/accounts_controller_spec.rb @@ -191,58 +191,6 @@ RSpec.describe Admin::AccountsController, type: :controller do end end - describe 'POST #disable' do - subject { post :disable, params: { id: account.id } } - - let(:current_user) { Fabricate(:user, admin: current_user_admin) } - let(:account) { Fabricate(:account, user: user) } - let(:user) { Fabricate(:user, disabled: false, admin: target_user_admin) } - - context 'when user is admin' do - let(:current_user_admin) { true } - - context 'when target user is admin' do - let(:target_user_admin) { true } - - it 'fails to disable account' do - is_expected.to have_http_status :forbidden - expect(user.reload).not_to be_disabled - end - end - - context 'when target user is not admin' do - let(:target_user_admin) { false } - - it 'succeeds in disabling account' do - is_expected.to redirect_to admin_account_path(account.id) - expect(user.reload).to be_disabled - end - end - end - - context 'when user is not admin' do - let(:current_user_admin) { false } - - context 'when target user is admin' do - let(:target_user_admin) { true } - - it 'fails to disable account' do - is_expected.to have_http_status :forbidden - expect(user.reload).not_to be_disabled - end - end - - context 'when target user is not admin' do - let(:target_user_admin) { false } - - it 'fails to disable account' do - is_expected.to have_http_status :forbidden - expect(user.reload).not_to be_disabled - end - end - end - end - describe 'POST #redownload' do subject { post :redownload, params: { id: account.id } } diff --git a/spec/controllers/admin/reports_controller_spec.rb b/spec/controllers/admin/reports_controller_spec.rb index bcc789c57..b428299ee 100644 --- a/spec/controllers/admin/reports_controller_spec.rb +++ b/spec/controllers/admin/reports_controller_spec.rb @@ -46,73 +46,37 @@ describe Admin::ReportsController do end end - describe 'PUT #update' do - describe 'with an unknown outcome' do - it 'rejects the change' do - report = Fabricate(:report) - put :update, params: { id: report, outcome: 'unknown' } - - expect(response).to have_http_status(404) - end - end - - describe 'with an outcome of `resolve`' do - it 'resolves the report' do - report = Fabricate(:report) - - put :update, params: { id: report, outcome: 'resolve' } - expect(response).to redirect_to(admin_reports_path) - report.reload - expect(report.action_taken_by_account).to eq user.account - expect(report.action_taken).to eq true - end - end - - describe 'with an outsome of `silence`' do - it 'silences the reported account' do - report = Fabricate(:report) - - put :update, params: { id: report, outcome: 'silence' } - expect(response).to redirect_to(admin_reports_path) - report.reload - expect(report.action_taken_by_account).to eq user.account - expect(report.action_taken).to eq true - expect(report.target_account).to be_silenced - end - end - - describe 'with an outsome of `reopen`' do - it 'reopens the report' do - report = Fabricate(:report) + describe 'POST #reopen' do + it 'reopens the report' do + report = Fabricate(:report) - put :update, params: { id: report, outcome: 'reopen' } - expect(response).to redirect_to(admin_report_path(report)) - report.reload - expect(report.action_taken_by_account).to eq nil - expect(report.action_taken).to eq false - end + put :reopen, params: { id: report } + expect(response).to redirect_to(admin_report_path(report)) + report.reload + expect(report.action_taken_by_account).to eq nil + expect(report.action_taken).to eq false end + end - describe 'with an outsome of `assign_to_self`' do - it 'reopens the report' do - report = Fabricate(:report) + describe 'POST #assign_to_self' do + it 'reopens the report' do + report = Fabricate(:report) - put :update, params: { id: report, outcome: 'assign_to_self' } - expect(response).to redirect_to(admin_report_path(report)) - report.reload - expect(report.assigned_account).to eq user.account - end + put :assign_to_self, params: { id: report } + expect(response).to redirect_to(admin_report_path(report)) + report.reload + expect(report.assigned_account).to eq user.account end + end - describe 'with an outsome of `unassign`' do - it 'reopens the report' do - report = Fabricate(:report) + describe 'POST #unassign' do + it 'reopens the report' do + report = Fabricate(:report) - put :update, params: { id: report, outcome: 'unassign' } - expect(response).to redirect_to(admin_report_path(report)) - report.reload - expect(report.assigned_account).to eq nil - end + put :unassign, params: { id: report } + expect(response).to redirect_to(admin_report_path(report)) + report.reload + expect(report.assigned_account).to eq nil end end end diff --git a/spec/controllers/admin/silences_controller_spec.rb b/spec/controllers/admin/silences_controller_spec.rb deleted file mode 100644 index 78560eb39..000000000 --- a/spec/controllers/admin/silences_controller_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -require 'rails_helper' - -describe Admin::SilencesController do - render_views - - before do - sign_in Fabricate(:user, admin: true), scope: :user - end - - describe 'POST #create' do - it 'redirects to admin accounts page' do - account = Fabricate(:account, silenced: false) - - post :create, params: { account_id: account.id } - - account.reload - expect(account.silenced?).to eq true - expect(response).to redirect_to(admin_accounts_path) - end - end - - describe 'DELETE #destroy' do - it 'redirects to admin accounts page' do - account = Fabricate(:account, silenced: true) - - delete :destroy, params: { account_id: account.id } - - account.reload - expect(account.silenced?).to eq false - expect(response).to redirect_to(admin_accounts_path) - end - end -end diff --git a/spec/controllers/admin/suspensions_controller_spec.rb b/spec/controllers/admin/suspensions_controller_spec.rb deleted file mode 100644 index 1bc33e490..000000000 --- a/spec/controllers/admin/suspensions_controller_spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require 'rails_helper' - -describe Admin::SuspensionsController do - render_views - - before do - sign_in Fabricate(:user, admin: true), scope: :user - end - - describe 'GET #new' do - it 'returns 200' do - get :new, params: { account_id: Fabricate(:account).id, report_id: Fabricate(:report).id } - expect(response).to have_http_status(200) - end - end - - describe 'POST #create' do - it 'redirects to admin accounts page' do - account = Fabricate(:account, suspended: false) - expect(Admin::SuspensionWorker).to receive(:perform_async).with(account.id) - - post :create, params: { account_id: account.id, form_admin_suspension_confirmation: { acct: account.acct } } - - expect(response).to redirect_to(admin_accounts_path) - end - end - - describe 'DELETE #destroy' do - it 'redirects to admin accounts page' do - account = Fabricate(:account, suspended: true) - - delete :destroy, params: { account_id: account.id } - - account.reload - expect(account.suspended?).to eq false - expect(response).to redirect_to(admin_accounts_path) - end - end -end diff --git a/spec/fabricators/account_warning_fabricator.rb b/spec/fabricators/account_warning_fabricator.rb new file mode 100644 index 000000000..db161d446 --- /dev/null +++ b/spec/fabricators/account_warning_fabricator.rb @@ -0,0 +1,5 @@ +Fabricator(:account_warning) do + account nil + target_account nil + text "MyText" +end diff --git a/spec/fabricators/account_warning_preset_fabricator.rb b/spec/fabricators/account_warning_preset_fabricator.rb new file mode 100644 index 000000000..6c0b87e7c --- /dev/null +++ b/spec/fabricators/account_warning_preset_fabricator.rb @@ -0,0 +1,3 @@ +Fabricator(:account_warning_preset) do + text "MyText" +end diff --git a/spec/mailers/previews/user_mailer_preview.rb b/spec/mailers/previews/user_mailer_preview.rb index d9cdb9264..53c836494 100644 --- a/spec/mailers/previews/user_mailer_preview.rb +++ b/spec/mailers/previews/user_mailer_preview.rb @@ -39,4 +39,9 @@ class UserMailerPreview < ActionMailer::Preview def backup_ready UserMailer.backup_ready(User.first, Backup.first) end + + # Preview this email at http://localhost:3000/rails/mailers/user_mailer/warning + def warning + UserMailer.warning(User.first, AccountWarning.new(text: '', action: :silence)) + end end diff --git a/spec/models/account_warning_preset_spec.rb b/spec/models/account_warning_preset_spec.rb new file mode 100644 index 000000000..a859a305f --- /dev/null +++ b/spec/models/account_warning_preset_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe AccountWarningPreset, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/account_warning_spec.rb b/spec/models/account_warning_spec.rb new file mode 100644 index 000000000..5286f9177 --- /dev/null +++ b/spec/models/account_warning_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe AccountWarning, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/admin/account_action_spec.rb b/spec/models/admin/account_action_spec.rb new file mode 100644 index 000000000..8c55cf4dd --- /dev/null +++ b/spec/models/admin/account_action_spec.rb @@ -0,0 +1,4 @@ +require 'rails_helper' + +RSpec.describe Admin::AccountAction, type: :model do +end -- cgit