Add ability to disable login and mark accounts as memorial (#5615)
Fix #5597
This commit is contained in:
parent
cbbeec05be
commit
1032f3994f
17 changed files with 168 additions and 39 deletions
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class AccountsController < BaseController
|
class AccountsController < BaseController
|
||||||
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload]
|
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :enable, :disable, :memorialize]
|
||||||
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
|
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
|
||||||
|
before_action :require_local_account!, only: [:enable, :disable, :memorialize]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@accounts = filtered_accounts.page(params[:page])
|
@accounts = filtered_accounts.page(params[:page])
|
||||||
|
@ -24,6 +25,21 @@ module Admin
|
||||||
redirect_to admin_account_path(@account.id)
|
redirect_to admin_account_path(@account.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def memorialize
|
||||||
|
@account.memorialize!
|
||||||
|
redirect_to admin_account_path(@account.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable
|
||||||
|
@account.user.enable!
|
||||||
|
redirect_to admin_account_path(@account.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def disable
|
||||||
|
@account.user.disable!
|
||||||
|
redirect_to admin_account_path(@account.id)
|
||||||
|
end
|
||||||
|
|
||||||
def redownload
|
def redownload
|
||||||
@account.reset_avatar!
|
@account.reset_avatar!
|
||||||
@account.reset_header!
|
@account.reset_header!
|
||||||
|
@ -42,6 +58,10 @@ module Admin
|
||||||
redirect_to admin_account_path(@account.id) if @account.local?
|
redirect_to admin_account_path(@account.id) if @account.local?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def require_local_account!
|
||||||
|
redirect_to admin_account_path(@account.id) unless @account.local? && @account.user.present?
|
||||||
|
end
|
||||||
|
|
||||||
def filtered_accounts
|
def filtered_accounts
|
||||||
AccountFilter.new(filter_params).results
|
AccountFilter.new(filter_params).results
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@account.update(suspended: false)
|
@account.unsuspend!
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
.landing-strip {
|
.landing-strip,
|
||||||
|
.memoriam-strip {
|
||||||
background: rgba(darken($ui-base-color, 7%), 0.8);
|
background: rgba(darken($ui-base-color, 7%), 0.8);
|
||||||
color: $ui-primary-color;
|
color: $ui-primary-color;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
@ -29,3 +30,7 @@
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.memoriam-strip {
|
||||||
|
background: rgba($base-shadow-color, 0.7);
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ class NotificationMailer < ApplicationMailer
|
||||||
@me = recipient
|
@me = recipient
|
||||||
@status = notification.target_status
|
@status = notification.target_status
|
||||||
|
|
||||||
|
return if @me.user.disabled?
|
||||||
|
|
||||||
locale_for_account(@me) do
|
locale_for_account(@me) do
|
||||||
thread_by_conversation(@status.conversation)
|
thread_by_conversation(@status.conversation)
|
||||||
mail to: @me.user.email, subject: I18n.t('notification_mailer.mention.subject', name: @status.account.acct)
|
mail to: @me.user.email, subject: I18n.t('notification_mailer.mention.subject', name: @status.account.acct)
|
||||||
|
@ -17,6 +19,8 @@ class NotificationMailer < ApplicationMailer
|
||||||
@me = recipient
|
@me = recipient
|
||||||
@account = notification.from_account
|
@account = notification.from_account
|
||||||
|
|
||||||
|
return if @me.user.disabled?
|
||||||
|
|
||||||
locale_for_account(@me) do
|
locale_for_account(@me) do
|
||||||
mail to: @me.user.email, subject: I18n.t('notification_mailer.follow.subject', name: @account.acct)
|
mail to: @me.user.email, subject: I18n.t('notification_mailer.follow.subject', name: @account.acct)
|
||||||
end
|
end
|
||||||
|
@ -27,6 +31,8 @@ class NotificationMailer < ApplicationMailer
|
||||||
@account = notification.from_account
|
@account = notification.from_account
|
||||||
@status = notification.target_status
|
@status = notification.target_status
|
||||||
|
|
||||||
|
return if @me.user.disabled?
|
||||||
|
|
||||||
locale_for_account(@me) do
|
locale_for_account(@me) do
|
||||||
thread_by_conversation(@status.conversation)
|
thread_by_conversation(@status.conversation)
|
||||||
mail to: @me.user.email, subject: I18n.t('notification_mailer.favourite.subject', name: @account.acct)
|
mail to: @me.user.email, subject: I18n.t('notification_mailer.favourite.subject', name: @account.acct)
|
||||||
|
@ -38,6 +44,8 @@ class NotificationMailer < ApplicationMailer
|
||||||
@account = notification.from_account
|
@account = notification.from_account
|
||||||
@status = notification.target_status
|
@status = notification.target_status
|
||||||
|
|
||||||
|
return if @me.user.disabled?
|
||||||
|
|
||||||
locale_for_account(@me) do
|
locale_for_account(@me) do
|
||||||
thread_by_conversation(@status.conversation)
|
thread_by_conversation(@status.conversation)
|
||||||
mail to: @me.user.email, subject: I18n.t('notification_mailer.reblog.subject', name: @account.acct)
|
mail to: @me.user.email, subject: I18n.t('notification_mailer.reblog.subject', name: @account.acct)
|
||||||
|
@ -48,6 +56,8 @@ class NotificationMailer < ApplicationMailer
|
||||||
@me = recipient
|
@me = recipient
|
||||||
@account = notification.from_account
|
@account = notification.from_account
|
||||||
|
|
||||||
|
return if @me.user.disabled?
|
||||||
|
|
||||||
locale_for_account(@me) do
|
locale_for_account(@me) do
|
||||||
mail to: @me.user.email, subject: I18n.t('notification_mailer.follow_request.subject', name: @account.acct)
|
mail to: @me.user.email, subject: I18n.t('notification_mailer.follow_request.subject', name: @account.acct)
|
||||||
end
|
end
|
||||||
|
@ -59,15 +69,11 @@ class NotificationMailer < ApplicationMailer
|
||||||
@notifications = Notification.where(account: @me, activity_type: 'Mention').where('created_at > ?', @since)
|
@notifications = Notification.where(account: @me, activity_type: 'Mention').where('created_at > ?', @since)
|
||||||
@follows_since = Notification.where(account: @me, activity_type: 'Follow').where('created_at > ?', @since).count
|
@follows_since = Notification.where(account: @me, activity_type: 'Follow').where('created_at > ?', @since).count
|
||||||
|
|
||||||
return if @notifications.empty?
|
return if @me.user.disabled? || @notifications.empty?
|
||||||
|
|
||||||
locale_for_account(@me) do
|
locale_for_account(@me) do
|
||||||
mail to: @me.user.email,
|
mail to: @me.user.email,
|
||||||
subject: I18n.t(
|
subject: I18n.t(:subject, scope: [:notification_mailer, :digest], count: @notifications.size)
|
||||||
:subject,
|
|
||||||
scope: [:notification_mailer, :digest],
|
|
||||||
count: @notifications.size
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ class UserMailer < Devise::Mailer
|
||||||
@token = token
|
@token = token
|
||||||
@instance = Rails.configuration.x.local_domain
|
@instance = Rails.configuration.x.local_domain
|
||||||
|
|
||||||
|
return if @resource.disabled?
|
||||||
|
|
||||||
I18n.with_locale(@resource.locale || I18n.default_locale) do
|
I18n.with_locale(@resource.locale || I18n.default_locale) do
|
||||||
mail to: @resource.unconfirmed_email.blank? ? @resource.email : @resource.unconfirmed_email, subject: I18n.t('devise.mailer.confirmation_instructions.subject', instance: @instance)
|
mail to: @resource.unconfirmed_email.blank? ? @resource.email : @resource.unconfirmed_email, subject: I18n.t('devise.mailer.confirmation_instructions.subject', instance: @instance)
|
||||||
end
|
end
|
||||||
|
@ -20,6 +22,8 @@ class UserMailer < Devise::Mailer
|
||||||
@token = token
|
@token = token
|
||||||
@instance = Rails.configuration.x.local_domain
|
@instance = Rails.configuration.x.local_domain
|
||||||
|
|
||||||
|
return if @resource.disabled?
|
||||||
|
|
||||||
I18n.with_locale(@resource.locale || I18n.default_locale) do
|
I18n.with_locale(@resource.locale || I18n.default_locale) do
|
||||||
mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject')
|
mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject')
|
||||||
end
|
end
|
||||||
|
@ -29,6 +33,8 @@ class UserMailer < Devise::Mailer
|
||||||
@resource = user
|
@resource = user
|
||||||
@instance = Rails.configuration.x.local_domain
|
@instance = Rails.configuration.x.local_domain
|
||||||
|
|
||||||
|
return if @resource.disabled?
|
||||||
|
|
||||||
I18n.with_locale(@resource.locale || I18n.default_locale) do
|
I18n.with_locale(@resource.locale || I18n.default_locale) do
|
||||||
mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject')
|
mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject')
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
# shared_inbox_url :string default(""), not null
|
# shared_inbox_url :string default(""), not null
|
||||||
# followers_url :string default(""), not null
|
# followers_url :string default(""), not null
|
||||||
# protocol :integer default("ostatus"), not null
|
# protocol :integer default("ostatus"), not null
|
||||||
|
# memorial :boolean default(FALSE), not null
|
||||||
#
|
#
|
||||||
|
|
||||||
class Account < ApplicationRecord
|
class Account < ApplicationRecord
|
||||||
|
@ -150,6 +151,20 @@ class Account < ApplicationRecord
|
||||||
ResolveRemoteAccountService.new.call(acct)
|
ResolveRemoteAccountService.new.call(acct)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def unsuspend!
|
||||||
|
transaction do
|
||||||
|
user&.enable! if local?
|
||||||
|
update!(suspended: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def memorialize!
|
||||||
|
transaction do
|
||||||
|
user&.disable! if local?
|
||||||
|
update!(memorial: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def keypair
|
def keypair
|
||||||
@keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
|
@keypair ||= OpenSSL::PKey::RSA.new(private_key || public_key)
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# email :string default(""), not null
|
# email :string default(""), not null
|
||||||
# account_id :integer not null
|
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# encrypted_password :string default(""), not null
|
# encrypted_password :string default(""), not null
|
||||||
|
@ -31,10 +30,13 @@
|
||||||
# last_emailed_at :datetime
|
# last_emailed_at :datetime
|
||||||
# otp_backup_codes :string is an Array
|
# otp_backup_codes :string is an Array
|
||||||
# filtered_languages :string default([]), not null, is an Array
|
# filtered_languages :string default([]), not null, is an Array
|
||||||
|
# account_id :integer not null
|
||||||
|
# disabled :boolean default(FALSE), not null
|
||||||
#
|
#
|
||||||
|
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
include Settings::Extend
|
include Settings::Extend
|
||||||
|
|
||||||
ACTIVE_DURATION = 14.days
|
ACTIVE_DURATION = 14.days
|
||||||
|
|
||||||
devise :registerable, :recoverable,
|
devise :registerable, :recoverable,
|
||||||
|
@ -72,12 +74,26 @@ class User < ApplicationRecord
|
||||||
confirmed_at.present?
|
confirmed_at.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def disable!
|
||||||
|
update!(disabled: true,
|
||||||
|
last_sign_in_at: current_sign_in_at,
|
||||||
|
current_sign_in_at: nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
def enable!
|
||||||
|
update!(disabled: false)
|
||||||
|
end
|
||||||
|
|
||||||
def disable_two_factor!
|
def disable_two_factor!
|
||||||
self.otp_required_for_login = false
|
self.otp_required_for_login = false
|
||||||
otp_backup_codes&.clear
|
otp_backup_codes&.clear
|
||||||
save!
|
save!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_for_authentication?
|
||||||
|
super && !disabled?
|
||||||
|
end
|
||||||
|
|
||||||
def setting_default_privacy
|
def setting_default_privacy
|
||||||
settings.default_privacy || (account.locked? ? 'private' : 'public')
|
settings.default_privacy || (account.locked? ? 'private' : 'public')
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SuspendAccountService < BaseService
|
class SuspendAccountService < BaseService
|
||||||
def call(account, remove_user = false)
|
def call(account, options = {})
|
||||||
@account = account
|
@account = account
|
||||||
|
@options = options
|
||||||
|
|
||||||
purge_user if remove_user
|
purge_user!
|
||||||
purge_profile
|
purge_profile!
|
||||||
purge_content
|
purge_content!
|
||||||
unsubscribe_push_subscribers
|
unsubscribe_push_subscribers!
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def purge_user
|
def purge_user!
|
||||||
@account.user.destroy
|
if @options[:remove_user]
|
||||||
|
@account.user&.destroy
|
||||||
|
else
|
||||||
|
@account.user&.disable!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def purge_content
|
def purge_content!
|
||||||
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
@account.statuses.reorder(nil).find_in_batches do |statuses|
|
||||||
BatchedRemoveStatusService.new.call(statuses)
|
BatchedRemoveStatusService.new.call(statuses)
|
||||||
end
|
end
|
||||||
|
@ -33,7 +38,7 @@ class SuspendAccountService < BaseService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def purge_profile
|
def purge_profile!
|
||||||
@account.suspended = true
|
@account.suspended = true
|
||||||
@account.display_name = ''
|
@account.display_name = ''
|
||||||
@account.note = ''
|
@account.note = ''
|
||||||
|
@ -42,7 +47,7 @@ class SuspendAccountService < BaseService
|
||||||
@account.save!
|
@account.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
def unsubscribe_push_subscribers
|
def unsubscribe_push_subscribers!
|
||||||
destroy_all(@account.subscriptions)
|
destroy_all(@account.subscriptions)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
|
.card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
|
||||||
.card__illustration
|
.card__illustration
|
||||||
- if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
|
- unless account.memorial?
|
||||||
.controls
|
- if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
|
||||||
- if current_account.following?(account)
|
.controls
|
||||||
= link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
|
- if current_account.following?(account)
|
||||||
= fa_icon 'user-times'
|
= link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
|
||||||
= t('accounts.unfollow')
|
= fa_icon 'user-times'
|
||||||
- else
|
= t('accounts.unfollow')
|
||||||
= link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
|
- else
|
||||||
= fa_icon 'user-plus'
|
= link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
|
||||||
= t('accounts.follow')
|
= fa_icon 'user-plus'
|
||||||
- elsif !user_signed_in?
|
= t('accounts.follow')
|
||||||
.controls
|
- elsif !user_signed_in?
|
||||||
.remote-follow
|
.controls
|
||||||
= link_to account_remote_follow_path(account), class: 'icon-button' do
|
.remote-follow
|
||||||
= fa_icon 'user-plus'
|
= link_to account_remote_follow_path(account), class: 'icon-button' do
|
||||||
= t('accounts.remote_follow')
|
= fa_icon 'user-plus'
|
||||||
|
= t('accounts.remote_follow')
|
||||||
|
|
||||||
.avatar= image_tag account.avatar.url(:original), class: 'u-photo'
|
.avatar= image_tag account.avatar.url(:original), class: 'u-photo'
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
= opengraph 'og:type', 'profile'
|
= opengraph 'og:type', 'profile'
|
||||||
= render 'og', account: @account, url: short_account_url(@account, only_path: false)
|
= render 'og', account: @account, url: short_account_url(@account, only_path: false)
|
||||||
|
|
||||||
- if show_landing_strip?
|
- if @account.memorial?
|
||||||
|
.memoriam-strip= t('in_memoriam_html')
|
||||||
|
- elsif show_landing_strip?
|
||||||
= render partial: 'shared/landing_strip', locals: { account: @account }
|
= render partial: 'shared/landing_strip', locals: { account: @account }
|
||||||
|
|
||||||
.h-feed
|
.h-feed
|
||||||
|
|
|
@ -18,6 +18,15 @@
|
||||||
%tr
|
%tr
|
||||||
%th= t('admin.accounts.email')
|
%th= t('admin.accounts.email')
|
||||||
%td= @account.user_email
|
%td= @account.user_email
|
||||||
|
%tr
|
||||||
|
%th= t('admin.accounts.login_status')
|
||||||
|
%td
|
||||||
|
- if @account.user&.disabled?
|
||||||
|
= t('admin.accounts.disabled')
|
||||||
|
= table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post
|
||||||
|
- else
|
||||||
|
= t('admin.accounts.enabled')
|
||||||
|
= table_link_to 'lock', t('admin.accounts.disable'), disable_admin_account_path(@account.id), method: :post
|
||||||
%tr
|
%tr
|
||||||
%th= t('admin.accounts.most_recent_ip')
|
%th= t('admin.accounts.most_recent_ip')
|
||||||
%td= @account.user_current_sign_in_ip
|
%td= @account.user_current_sign_in_ip
|
||||||
|
@ -65,6 +74,8 @@
|
||||||
= link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button'
|
= link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button'
|
||||||
- if @account.user&.otp_required_for_login?
|
- if @account.user&.otp_required_for_login?
|
||||||
= link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button'
|
= link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button'
|
||||||
|
- unless @account.memorial?
|
||||||
|
= link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button'
|
||||||
- else
|
- else
|
||||||
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button'
|
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button'
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,6 @@ class Admin::SuspensionWorker
|
||||||
sidekiq_options queue: 'pull'
|
sidekiq_options queue: 'pull'
|
||||||
|
|
||||||
def perform(account_id, remove_user = false)
|
def perform(account_id, remove_user = false)
|
||||||
SuspendAccountService.new.call(Account.find(account_id), remove_user)
|
SuspendAccountService.new.call(Account.find(account_id), remove_user: remove_user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -62,11 +62,15 @@ en:
|
||||||
by_domain: Domain
|
by_domain: Domain
|
||||||
confirm: Confirm
|
confirm: Confirm
|
||||||
confirmed: Confirmed
|
confirmed: Confirmed
|
||||||
|
disable: Disable
|
||||||
disable_two_factor_authentication: Disable 2FA
|
disable_two_factor_authentication: Disable 2FA
|
||||||
|
disabled: Disabled
|
||||||
display_name: Display name
|
display_name: Display name
|
||||||
domain: Domain
|
domain: Domain
|
||||||
edit: Edit
|
edit: Edit
|
||||||
email: E-mail
|
email: E-mail
|
||||||
|
enable: Enable
|
||||||
|
enabled: Enabled
|
||||||
feed_url: Feed URL
|
feed_url: Feed URL
|
||||||
followers: Followers
|
followers: Followers
|
||||||
followers_url: Followers URL
|
followers_url: Followers URL
|
||||||
|
@ -78,7 +82,9 @@ en:
|
||||||
local: Local
|
local: Local
|
||||||
remote: Remote
|
remote: Remote
|
||||||
title: Location
|
title: Location
|
||||||
|
login_status: Login status
|
||||||
media_attachments: Media attachments
|
media_attachments: Media attachments
|
||||||
|
memorialize: Turn into memoriam
|
||||||
moderation:
|
moderation:
|
||||||
all: All
|
all: All
|
||||||
silenced: Silenced
|
silenced: Silenced
|
||||||
|
@ -379,6 +385,7 @@ en:
|
||||||
following: Following list
|
following: Following list
|
||||||
muting: Muting list
|
muting: Muting list
|
||||||
upload: Upload
|
upload: Upload
|
||||||
|
in_memoriam_html: In Memoriam.
|
||||||
landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
|
landing_strip_html: "<strong>%{name}</strong> is a user on %{link_to_root_path}. You can follow them or interact with them if you have an account anywhere in the fediverse."
|
||||||
landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
|
landing_strip_signup_html: If you don't, you can <a href="%{sign_up_path}">sign up here</a>.
|
||||||
media_attachments:
|
media_attachments:
|
||||||
|
|
|
@ -126,7 +126,10 @@ Rails.application.routes.draw do
|
||||||
member do
|
member do
|
||||||
post :subscribe
|
post :subscribe
|
||||||
post :unsubscribe
|
post :unsubscribe
|
||||||
|
post :enable
|
||||||
|
post :disable
|
||||||
post :redownload
|
post :redownload
|
||||||
|
post :memorialize
|
||||||
end
|
end
|
||||||
|
|
||||||
resource :reset, only: [:create]
|
resource :reset, only: [:create]
|
||||||
|
|
15
db/migrate/20171107143332_add_memorial_to_accounts.rb
Normal file
15
db/migrate/20171107143332_add_memorial_to_accounts.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require Rails.root.join('lib', 'mastodon', 'migration_helpers')
|
||||||
|
|
||||||
|
class AddMemorialToAccounts < ActiveRecord::Migration[5.1]
|
||||||
|
include Mastodon::MigrationHelpers
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
safety_assured { add_column_with_default :accounts, :memorial, :bool, default: false }
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :accounts, :memorial
|
||||||
|
end
|
||||||
|
end
|
15
db/migrate/20171107143624_add_disabled_to_users.rb
Normal file
15
db/migrate/20171107143624_add_disabled_to_users.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require Rails.root.join('lib', 'mastodon', 'migration_helpers')
|
||||||
|
|
||||||
|
class AddDisabledToUsers < ActiveRecord::Migration[5.1]
|
||||||
|
include Mastodon::MigrationHelpers
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
safety_assured { add_column_with_default :users, :disabled, :bool, default: false }
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :users, :disabled
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20171020084748) do
|
ActiveRecord::Schema.define(version: 20171107143624) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -71,6 +71,7 @@ ActiveRecord::Schema.define(version: 20171020084748) do
|
||||||
t.string "shared_inbox_url", default: "", null: false
|
t.string "shared_inbox_url", default: "", null: false
|
||||||
t.string "followers_url", default: "", null: false
|
t.string "followers_url", default: "", null: false
|
||||||
t.integer "protocol", default: 0, null: false
|
t.integer "protocol", default: 0, null: false
|
||||||
|
t.boolean "memorial", default: false, null: false
|
||||||
t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
|
t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin
|
||||||
t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower"
|
t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower"
|
||||||
t.index ["uri"], name: "index_accounts_on_uri"
|
t.index ["uri"], name: "index_accounts_on_uri"
|
||||||
|
@ -435,6 +436,7 @@ ActiveRecord::Schema.define(version: 20171020084748) do
|
||||||
t.string "otp_backup_codes", array: true
|
t.string "otp_backup_codes", array: true
|
||||||
t.string "filtered_languages", default: [], null: false, array: true
|
t.string "filtered_languages", default: [], null: false, array: true
|
||||||
t.bigint "account_id", null: false
|
t.bigint "account_id", null: false
|
||||||
|
t.boolean "disabled", default: false, null: false
|
||||||
t.index ["account_id"], name: "index_users_on_account_id"
|
t.index ["account_id"], name: "index_users_on_account_id"
|
||||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
|
|
Loading…
Reference in a new issue