diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 6d2aa0641f..1ec35f8105 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -38,6 +38,7 @@ linters: - 'app/views/invites/_form.html.haml' - 'app/views/relationships/_account.html.haml' - 'app/views/shared/_og.html.haml' + - 'app/views/application/_sidebar.html.haml' # Offense count: 3 IdNames: diff --git a/README.md b/README.md index a4d5642d57..51ea436c6a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ kmyblue はフォーク名であり、同時に[サーバー名](https://kmy.blu kmyblue は AGPL ライセンスで公開されているため、どなたでも自由にフォークし、このソースコードを元に自分でサーバーを立てて公開することができます。また ActivityPub に参加することもできます。サーバーkmyblueは創作作家向けのものですが、フォークとしてのkmyblueは作者の嫌いな政治に関する過激な話を取り扱うコミュニティ、創作活動の一部(エロ関係含む)または全体を否定するコミュニティなども平等にお使いいただけますし、サーバーkmyblueのルールを適用する必要もありません。 ただし kmyblue においてテストコードは飾りでしかないため、不具合が発生しても自己責任になります。既知のバグもいくつかありますし、直す予定のないものも含まれます。 -テストコードは飾りですが、Lint は動いています。 +テストコード、Lint どちらも動いています。 ## kmyblue の強み diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 96bf2048c0..5920dcdee8 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -88,15 +88,18 @@ module Admin end def update_params - params.require(:domain_block).permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.require(:domain_block).permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, + :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) end def resource_params - params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, + :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) end def form_domain_block_batch_params - params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous]) + params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, + :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous]) end def action_from_button diff --git a/app/controllers/api/v1/admin/domain_blocks_controller.rb b/app/controllers/api/v1/admin/domain_blocks_controller.rb index ef0f4e464a..bd0660dbaa 100644 --- a/app/controllers/api/v1/admin/domain_blocks_controller.rb +++ b/app/controllers/api/v1/admin/domain_blocks_controller.rb @@ -69,7 +69,8 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController end def domain_block_params - params.permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_reports, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.permit(:severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_reports, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, + :reject_new_follow, :detect_invalid_subscription, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) end def insert_pagination_headers @@ -101,6 +102,7 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController end def resource_params - params.permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) + params.permit(:domain, :severity, :reject_media, :reject_favourite, :reject_reply, :reject_reply_exclude_followers, :reject_send_not_public_searchability, :reject_send_public_unlisted, :reject_send_dissubscribable, :reject_send_media, :reject_send_sensitive, :reject_hashtag, :reject_straight_follow, + :reject_new_follow, :detect_invalid_subscription, :reject_reports, :private_comment, :public_comment, :obfuscate, :hidden, :hidden_anonymous) end end diff --git a/app/javascript/mastodon/actions/antennas.js b/app/javascript/mastodon/actions/antennas.js index 6bb0de369c..d8a6a405d6 100644 --- a/app/javascript/mastodon/actions/antennas.js +++ b/app/javascript/mastodon/actions/antennas.js @@ -1,4 +1,5 @@ import api from '../api'; + import { importFetchedAccounts } from './importer'; export const ANTENNAS_FETCH_REQUEST = 'ANTENNAS_FETCH_REQUEST'; diff --git a/app/javascript/mastodon/actions/emoji_reactions.js b/app/javascript/mastodon/actions/emoji_reactions.js index 191d8dda8d..6b97b1f743 100644 --- a/app/javascript/mastodon/actions/emoji_reactions.js +++ b/app/javascript/mastodon/actions/emoji_reactions.js @@ -1,4 +1,5 @@ import api, { getLinks } from '../api'; + import { importFetchedStatuses } from './importer'; export const EMOJI_REACTED_STATUSES_FETCH_REQUEST = 'EMOJI_REACTED_STATUSES_FETCH_REQUEST'; diff --git a/app/javascript/mastodon/components/emoji_view.jsx b/app/javascript/mastodon/components/emoji_view.jsx index 68bf808790..39e28b2673 100644 --- a/app/javascript/mastodon/components/emoji_view.jsx +++ b/app/javascript/mastodon/components/emoji_view.jsx @@ -1,5 +1,6 @@ -import { PureComponent } from 'react'; import PropTypes from 'prop-types'; +import { PureComponent } from 'react'; + import emojify from '../features/emoji/emoji'; export default class EmojiView extends PureComponent { diff --git a/app/javascript/mastodon/components/short_number.tsx b/app/javascript/mastodon/components/short_number.tsx index 474288d6bd..15d6642a3b 100644 --- a/app/javascript/mastodon/components/short_number.tsx +++ b/app/javascript/mastodon/components/short_number.tsx @@ -33,7 +33,11 @@ export const ShortNumberRenderer: React.FC = ({ const customRenderer = children ?? renderer ?? null; - const displayNumber = !isHide ? : -; + const displayNumber = !isHide ? ( + + ) : ( + - + ); return ( customRenderer?.(displayNumber, pluralReady(value, division)) ?? diff --git a/app/javascript/mastodon/components/status_emoji_reactions_bar.jsx b/app/javascript/mastodon/components/status_emoji_reactions_bar.jsx index f3c3a4cd1d..7cc088dda8 100644 --- a/app/javascript/mastodon/components/status_emoji_reactions_bar.jsx +++ b/app/javascript/mastodon/components/status_emoji_reactions_bar.jsx @@ -1,8 +1,12 @@ -import { PureComponent } from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; +import { PureComponent } from 'react'; + import { injectIntl } from 'react-intl'; + import classNames from 'classnames'; + +import ImmutablePropTypes from 'react-immutable-proptypes'; + import EmojiView from './emoji_view'; class EmojiReactionButton extends PureComponent { diff --git a/app/javascript/mastodon/features/antenna_adder/components/account.jsx b/app/javascript/mastodon/features/antenna_adder/components/account.jsx index e2828f5ab3..31a2e96379 100644 --- a/app/javascript/mastodon/features/antenna_adder/components/account.jsx +++ b/app/javascript/mastodon/features/antenna_adder/components/account.jsx @@ -1,10 +1,12 @@ -import { connect } from 'react-redux'; -import { makeGetAccount } from '../../../selectors'; -import ImmutablePureComponent from 'react-immutable-pure-component'; +import { injectIntl } from 'react-intl'; + import ImmutablePropTypes from 'react-immutable-proptypes'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { connect } from 'react-redux'; + import { Avatar } from '../../../components/avatar'; import { DisplayName } from '../../../components/display_name'; -import { injectIntl } from 'react-intl'; +import { makeGetAccount } from '../../../selectors'; const makeMapStateToProps = () => { const getAccount = makeGetAccount(); diff --git a/app/javascript/mastodon/features/antenna_adder/components/antenna.jsx b/app/javascript/mastodon/features/antenna_adder/components/antenna.jsx index a6ab1549e9..d2833d3e0d 100644 --- a/app/javascript/mastodon/features/antenna_adder/components/antenna.jsx +++ b/app/javascript/mastodon/features/antenna_adder/components/antenna.jsx @@ -1,12 +1,16 @@ import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { IconButton } from '../../../components/icon_button'; + import { defineMessages, injectIntl } from 'react-intl'; -import { removeFromAntennaAdder, addToAntennaAdder } from '../../../actions/antennas'; + +import ImmutablePropTypes from 'react-immutable-proptypes'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { connect } from 'react-redux'; + import { Icon } from 'mastodon/components/icon'; +import { removeFromAntennaAdder, addToAntennaAdder } from '../../../actions/antennas'; +import { IconButton } from '../../../components/icon_button'; + const messages = defineMessages({ remove: { id: 'lists.account.remove', defaultMessage: 'Remove from list' }, add: { id: 'lists.account.add', defaultMessage: 'Add to list' }, diff --git a/app/javascript/mastodon/features/antenna_adder/index.jsx b/app/javascript/mastodon/features/antenna_adder/index.jsx index 59e402bce3..b8ec30d0e1 100644 --- a/app/javascript/mastodon/features/antenna_adder/index.jsx +++ b/app/javascript/mastodon/features/antenna_adder/index.jsx @@ -1,12 +1,16 @@ import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { connect } from 'react-redux'; -import ImmutablePureComponent from 'react-immutable-pure-component'; + import { injectIntl } from 'react-intl'; -import { setupAntennaAdder, resetAntennaAdder } from '../../actions/antennas'; + +import ImmutablePropTypes from 'react-immutable-proptypes'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { connect } from 'react-redux'; import { createSelector } from 'reselect'; -import Antenna from './components/antenna'; + +import { setupAntennaAdder, resetAntennaAdder } from '../../actions/antennas'; + import Account from './components/account'; +import Antenna from './components/antenna'; // hack const getOrderedAntennas = createSelector([state => state.get('antennas')], antennas => { diff --git a/app/javascript/mastodon/features/compose/containers/markdown_button_container.js b/app/javascript/mastodon/features/compose/containers/markdown_button_container.js index 1f5604f97b..8dc086e340 100644 --- a/app/javascript/mastodon/features/compose/containers/markdown_button_container.js +++ b/app/javascript/mastodon/features/compose/containers/markdown_button_container.js @@ -1,8 +1,10 @@ -import { connect } from 'react-redux'; -import TextIconButton from '../components/text_icon_button'; -import { changeComposeMarkdown } from '../../../actions/compose'; import { injectIntl, defineMessages } from 'react-intl'; +import { connect } from 'react-redux'; + +import { changeComposeMarkdown } from '../../../actions/compose'; +import TextIconButton from '../components/text_icon_button'; + const messages = defineMessages({ marked: { id: 'compose_form.markdown.marked', defaultMessage: 'Markdown is enabled' }, unmarked: { id: 'compose_form.markdown.unmarked', defaultMessage: 'Markdown is disabled' }, diff --git a/app/javascript/mastodon/features/emoji_reacted_statuses/index.jsx b/app/javascript/mastodon/features/emoji_reacted_statuses/index.jsx index 35b19cf155..ad713f2d64 100644 --- a/app/javascript/mastodon/features/emoji_reacted_statuses/index.jsx +++ b/app/javascript/mastodon/features/emoji_reacted_statuses/index.jsx @@ -1,10 +1,15 @@ -import { debounce } from 'lodash'; import PropTypes from 'prop-types'; + +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; + import { Helmet } from 'react-helmet'; + import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; + +import { debounce } from 'lodash'; + import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns'; import { fetchEmojiReactedStatuses, expandEmojiReactedStatuses } from 'mastodon/actions/emoji_reactions'; import ColumnHeader from 'mastodon/components/column_header'; diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index 1872d9f689..9e28b5617f 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -446,7 +446,6 @@ class Notification extends ImmutablePureComponent { renderWarning (notification) { const { intl, unread } = this.props; - console.dir(notification); return ( diff --git a/app/javascript/mastodon/reducers/antenna_adder.js b/app/javascript/mastodon/reducers/antenna_adder.js index d3b98d63fd..8448d6984f 100644 --- a/app/javascript/mastodon/reducers/antenna_adder.js +++ b/app/javascript/mastodon/reducers/antenna_adder.js @@ -1,4 +1,5 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; + import { ANTENNA_ADDER_RESET, ANTENNA_ADDER_SETUP, diff --git a/app/javascript/mastodon/reducers/antenna_editor.js b/app/javascript/mastodon/reducers/antenna_editor.js index 2219aa7dfc..c1de305514 100644 --- a/app/javascript/mastodon/reducers/antenna_editor.js +++ b/app/javascript/mastodon/reducers/antenna_editor.js @@ -1,4 +1,5 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; + import { ANTENNA_ACCOUNTS_FETCH_REQUEST, ANTENNA_ACCOUNTS_FETCH_SUCCESS, diff --git a/app/javascript/mastodon/reducers/antennas.js b/app/javascript/mastodon/reducers/antennas.js index e20cab981a..1909fc96c0 100644 --- a/app/javascript/mastodon/reducers/antennas.js +++ b/app/javascript/mastodon/reducers/antennas.js @@ -1,7 +1,8 @@ +import { Map as ImmutableMap, fromJS } from 'immutable'; + import { ANTENNAS_FETCH_SUCCESS, } from '../actions/antennas'; -import { Map as ImmutableMap, fromJS } from 'immutable'; const initialState = ImmutableMap(); diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 98db5802f6..7febce7645 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -507,7 +507,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity SCAN_SEARCHABILITY_FEDIBIRD_RE = /searchable_by_(all_users|followers_only|reacted_users_only|nobody)/ def searchability - searchability_from_audience || searchability_from_bio || (marked_as_misskey_searchability? ? :public : nil) + searchability_from_audience || searchability_from_bio || (misskey_software? ? misskey_searchability : nil) end def searchability_from_bio @@ -522,14 +522,26 @@ class ActivityPub::Activity::Create < ActivityPub::Activity searchability = :public if %w(public all_users).include?(searchability) searchability = :private if %w(followers followers_only).include?(searchability) - searchability = :limited if %w(private reacted_users_only).include?(searchability) - searchability = :direct if %w(reactors nobody).include?(searchability) + searchability = :direct if %w(reactors reacted_users_only).include?(searchability) + searchability = :limited if %w(private nobody).include?(searchability) searchability end - def marked_as_misskey_searchability? - @marked_as_misskey_searchability ||= DomainBlock.detect_invalid_subscription?(@account.domain) + def instance_info + @instance_info ||= InstanceInfo.find_by(domain: @account.domain) + end + + def misskey_software? + info = instance_info + return false if info.nil? + + %w(misskey calckey firefish).include?(info.software) + end + + def misskey_searchability + visibility = visibility_from_audience + %i(public unlisted).include?(visibility) ? :public : :limited end def visibility_from_audience diff --git a/app/lib/status_reach_finder.rb b/app/lib/status_reach_finder.rb index 8d621b3fe8..6cce4e04fb 100644 --- a/app/lib/status_reach_finder.rb +++ b/app/lib/status_reach_finder.rb @@ -153,9 +153,10 @@ class StatusReachFinder end def banned_domains_for_misskey_of_status(status) - blocks = DomainBlock.where(domain: nil) - blocks = blocks.or(DomainBlock.where(detect_invalid_subscription: true)) if status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription - blocks = blocks.or(DomainBlock.where(detect_invalid_subscription: true)) if status.unlisted_visibility? && status.account.user&.setting_reject_unlisted_subscription - blocks.pluck(:domain).uniq + return [] unless (status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription) || (status.unlisted_visibility? && status.account.user&.setting_reject_unlisted_subscription) + + from_info = InstanceInfo.where(software: %w(misskey calckey firefish)).pluck(:domain) + from_domain_block = DomainBlock.where(detect_invalid_subscription: true).pluck(:domain) + (from_info + from_domain_block).uniq end end diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index 6068a6b08d..fb5da847ef 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -40,7 +40,7 @@ class CustomEmoji < ApplicationRecord belongs_to :category, class_name: 'CustomEmojiCategory', optional: true has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode, inverse_of: false - has_many :emoji_reactions, inverse_of: :custom_emoji, dependent: :destroy + has_many :emoji_reactions, inverse_of: :custom_emoji has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set modify-date +set create-date' } }, validate_media_type: false diff --git a/app/models/instance.rb b/app/models/instance.rb index 17ee0cbb1e..0fb1d3e96a 100644 --- a/app/models/instance.rb +++ b/app/models/instance.rb @@ -19,6 +19,7 @@ class Instance < ApplicationRecord belongs_to :domain_block belongs_to :domain_allow belongs_to :unavailable_domain # skipcq: RB-RL1031 + belongs_to :instance_info end scope :searchable, -> { where.not(domain: DomainBlock.select(:domain)) } diff --git a/app/models/instance_info.rb b/app/models/instance_info.rb new file mode 100644 index 0000000000..297134884f --- /dev/null +++ b/app/models/instance_info.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: instance_infos +# +# id :bigint(8) not null, primary key +# domain :string default(""), not null +# software :string default(""), not null +# version :string default(""), not null +# data :jsonb not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class InstanceInfo < ApplicationRecord +end diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 2007e77fa2..997600489f 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -60,6 +60,7 @@ class UserSettings setting :pending_account, default: true setting :trends, default: true setting :appeal, default: true + setting :warning, default: true end namespace :interactions do diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index 1b4dec20dc..2a07baab84 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -66,7 +66,11 @@ class REST::StatusSerializer < ActiveModel::Serializer end def visibility_ex - object.visibility + if object.limited_visibility? + 'private' + else + object.visibility + end end def searchability diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 9c2bda08fa..24a68a8c21 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -46,6 +46,7 @@ class ActivityPub::ProcessAccountService < BaseService end create_account + fetch_instance_info end update_account @@ -81,7 +82,7 @@ class ActivityPub::ProcessAccountService < BaseService @account.suspended_at = domain_block.created_at if auto_suspend? @account.suspension_origin = :local if auto_suspend? @account.silenced_at = domain_block.created_at if auto_silence? - @account.searchability = :private # not null + @account.searchability = :direct # not null @account.dissubscribable = false # not null set_immediate_protocol_attributes! @@ -207,6 +208,10 @@ class ActivityPub::ProcessAccountService < BaseService AccountMergingWorker.perform_async(@account.id) end + def fetch_instance_info + FetchInstanceInfoWorker.perform_async(@account.domain) unless InstanceInfo.exists?(domain: @account.domain) + end + def actor_type if @json['type'].is_a?(Array) @json['type'].find { |type| ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(type) } @@ -258,7 +263,7 @@ class ActivityPub::ProcessAccountService < BaseService bio = searchability_from_bio return bio unless bio.nil? - return marked_as_misskey_searchability? ? :public : :private + return misskey_software? ? :public : :direct end if audience_searchable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) } @@ -282,14 +287,21 @@ class ActivityPub::ProcessAccountService < BaseService searchability = :public if %w(public all_users).include?(searchability) searchability = :private if %w(followers followers_only).include?(searchability) - searchability = :limited if %w(private reacted_users_only).include?(searchability) - searchability = :direct if %w(reactors nobody).include?(searchability) + searchability = :direct if %w(reactors reacted_users_only).include?(searchability) + searchability = :limited if %w(private nobody).include?(searchability) searchability end - def marked_as_misskey_searchability? - domain_block&.detect_invalid_subscription + def instance_info + @instance_info ||= InstanceInfo.find_by(domain: @domain) + end + + def misskey_software? + info = instance_info + return false if info.nil? + + %w(misskey calckey firefish).include?(info.software) end def subscribable_by diff --git a/app/services/search_service.rb b/app/services/search_service.rb index fedc1f7129..590a4e1106 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -45,7 +45,7 @@ class SearchService < BaseService end def perform_statuses_search! - privacy_definition = parsed_query.apply(StatusesIndex.filter(term: { searchable_by: @account.id }).track_scores(true).min_score(@min_score)) + privacy_definition = parsed_query.apply(StatusesIndex.filter(terms: { searchability: %w(public private direct) }).filter(term: { searchable_by: @account.id }).track_scores(true).min_score(@min_score)) # 'direct' searchability posts are NOT in here because it's already added at previous line. case @searchability diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb index 9a8d23cb7e..5201620be4 100644 --- a/app/services/update_status_service.rb +++ b/app/services/update_status_service.rb @@ -43,6 +43,7 @@ class UpdateStatusService < BaseService update_metadata! broadcast_updates! + @status.reload @status rescue NoChangesSubmittedError # For calls that result in no changes, swallow the error diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index 3e4c41f737..9612f1e58d 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -1,6 +1,10 @@ - content_for :page_title do = @instance.domain +-if @instance.instance_info.present? + %p + = "#{@instance.instance_info.software} #{@instance.instance_info.version}" + - content_for :header_tags do = javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous' diff --git a/app/views/admin/media_attachments/_media_attachment.html.haml b/app/views/admin/media_attachments/_media_attachment.html.haml index 7aa9be605c..9e964a29ab 100644 --- a/app/views/admin/media_attachments/_media_attachment.html.haml +++ b/app/views/admin/media_attachments/_media_attachment.html.haml @@ -4,7 +4,7 @@ %tbody %tr %td - %img{ src: media_attachment.url, class: 'image' } + %img.image{ src: media_attachment.url, alt: '' } .detailed-status__meta - if media_attachment.status.application = media_attachment.status.application.name diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml index 08478a41f2..8992cc6d5a 100644 --- a/app/views/admin/statuses/show.html.haml +++ b/app/views/admin/statuses/show.html.haml @@ -45,7 +45,7 @@ %th= t('admin.statuses.favourites') %td= friendly_number_to_human @status.favourites_count -%div.action-buttons +.action-buttons %div - if @account.local? = link_to t('admin.statuses.remove_history'), remove_history_admin_account_status_path(@account.id), data: { confirm: t('admin.statuses.are_you_sure') }, method: :post, class: 'button' if can?(:warn, @account) diff --git a/app/views/antennas/_antenna_fields.html.haml b/app/views/antennas/_antenna_fields.html.haml index 9a4c9de4e4..201452c594 100644 --- a/app/views/antennas/_antenna_fields.html.haml +++ b/app/views/antennas/_antenna_fields.html.haml @@ -32,7 +32,7 @@ %h4= t('antennas.contexts.account') %p.hint= t 'antennas.edit.accounts_hint' -.fields-row +.fields-row .fields-row__column.fields-row__column-6.fields-group = f.input :accounts_raw, wrapper: :with_label, as: :text, input_html: { rows: 5 }, label: t('antennas.edit.accounts_raw') .fields-row__column.fields-row__column-6.fields-group @@ -40,7 +40,7 @@ %h4= t('antennas.contexts.tag') -.fields-row +.fields-row .fields-row__column.fields-row__column-6.fields-group = f.input :tags_raw, wrapper: :with_label, as: :text, input_html: { rows: 5 }, label: t('antennas.edit.tags_raw') .fields-row__column.fields-row__column-6.fields-group @@ -49,7 +49,7 @@ %h4= t('antennas.contexts.keyword') %p.hint= t 'antennas.edit.keywords_hint' -.fields-row +.fields-row .fields-row__column.fields-row__column-6.fields-group = f.input :keywords_raw, wrapper: :with_label, as: :text, input_html: { rows: 5 }, label: t('antennas.edit.keywords_raw') .fields-row__column.fields-row__column-6.fields-group diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 648a64d4d3..c59ba6c823 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -38,7 +38,7 @@ = yield :header_tags - %script(src="https://www.googletagmanager.com/gtag/js?id=AW-11130587137" async) + %script{ src="https://www.googletagmanager.com/gtag/js?id=AW-11130587137" async } :javascript window.dataLayer = window.dataLayer || []; diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index 313a7aa842..cd08c25e5e 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -78,7 +78,7 @@ .fields-group = f.input :my_actor_type, collection: ['person', 'bot'],label_method: lambda { |item| safe_join([t("simple_form.labels.defaults.#{item}"), content_tag(:span, I18n.t("simple_form.hints.defaults.#{item}"), class: 'hint')]) }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label - -#.fields-group + .fields-group = f.input :group_allow_private_message, as: :boolean, wrapper: :with_label, kmyblue: true, hint: t('simple_form.hints.defaults.group_allow_private_message') .actions diff --git a/app/workers/fetch_instance_info_worker.rb b/app/workers/fetch_instance_info_worker.rb new file mode 100644 index 0000000000..2700f88e13 --- /dev/null +++ b/app/workers/fetch_instance_info_worker.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +class FetchInstanceInfoWorker + include Sidekiq::Worker + include JsonLdHelper + include Redisable + include Lockable + + class Error < StandardError; end + class GoneError < Error; end + class RequestError < Error; end + + SUPPORTED_NOTEINFO_RELS = ['http://nodeinfo.diaspora.software/ns/schema/2.0', 'http://nodeinfo.diaspora.software/ns/schema/2.1'].freeze + + def perform(domain) + @instance = Instance.find_by(domain: domain) + return if !@instance || @instance.unavailable_domain.present? + + with_redis_lock("instance_info:#{domain}") do + link = nodeinfo_link + return if link.nil? + + update_info!(link) + end + end + + private + + def nodeinfo_link + nodeinfo = fetch_json("https://#{@instance.domain}/.well-known/nodeinfo") + return nil if nodeinfo.nil? || !nodeinfo.key?('links') + + nodeinfo_links = nodeinfo['links'] + return nil if !nodeinfo_links.is_a?(Array) || nodeinfo_links.blank? + + nodeinfo_link = nodeinfo_links.find { |item| item.key?('rel') && item.key?('href') && SUPPORTED_NOTEINFO_RELS.include?(item['rel']) } + return nil if nodeinfo_link.nil? || nodeinfo_link['href'].nil? || !nodeinfo_link['href'].start_with?('http') + + nodeinfo_link['href'] + end + + def update_info!(url) + content = fetch_json(url) + return nil if content.nil? || !content.key?('software') || !content['software'].key?('name') + + software = content['software']['name'] + version = content['software'].key?('version') ? content['software']['version'] : '' + + exists = @instance.instance_info + if exists.nil? + InstanceInfo.create!(domain: @instance.domain, software: software, version: version, data: content) + else + exists.software = software + exists.version = version + exists.data = content + exists.save! + end + end + + def fetch_json(url) + build_request(url).perform do |response| + if [200, 203].include?(response.code) + raise Mastodon::UnexpectedResponseError, response unless response_successful?(response) || response_error_unsalvageable?(response) + + body_to_json(response.body_with_limit) + elsif response.code == 410 + raise FetchInstanceInfoWorker::GoneError, "#{domain} is gone from the server" + else + raise FetchInstanceInfoWorker::RequestError, "Request for #{domain} returned HTTP #{response.code}" + end + end + end + + def build_request(url) + Request.new(:get, url).add_headers('Accept' => 'application/jrd+json, application/json') + end +end diff --git a/app/workers/scheduler/update_instance_info_scheduler.rb b/app/workers/scheduler/update_instance_info_scheduler.rb new file mode 100644 index 0000000000..e4d1230a78 --- /dev/null +++ b/app/workers/scheduler/update_instance_info_scheduler.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class Scheduler::UpdateInstanceInfoScheduler + include Sidekiq::Worker + + sidekiq_options retry: 1 + + def perform + Instance.select(:domain).reorder(nil).find_in_batches do |instances| + FetchInstanceInfoWorker.push_bulk(instances) do |instance| + [instance.domain] + end + end + end +end diff --git a/config/brakeman.ignore b/config/brakeman.ignore index 02ce23a075..a12fb26caf 100644 --- a/config/brakeman.ignore +++ b/config/brakeman.ignore @@ -57,6 +57,52 @@ ], "note": "" }, + { + "warning_type": "Mass Assignment", + "warning_code": 105, + "fingerprint": "874be88fedf4c680926845e9a588d3197765a6ccbfdd76466b44cc00151c612e", + "check_name": "PermitAttributes", + "message": "Potentially dangerous key allowed for mass assignment", + "file": "app/controllers/api/v1/admin/reports_controller.rb", + "line": 88, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit(:resolved, :account_id, :target_account_id)", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V1::Admin::ReportsController", + "method": "filter_params" + }, + "user_input": ":account_id", + "confidence": "High", + "cwe_id": [ + 915 + ], + "note": "" + }, + { + "warning_type": "Mass Assignment", + "warning_code": 105, + "fingerprint": "ab5035dd1a9f8c3a8d92fb2c37e8fe86fede4f87c91b71aa32e89c9eede602fc", + "check_name": "PermitAttributes", + "message": "Potentially dangerous key allowed for mass assignment", + "file": "app/controllers/api/v1/notifications_controller.rb", + "line": 81, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit(:account_id, :types => ([]), :exclude_types => ([]))", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V1::NotificationsController", + "method": "browserable_params" + }, + "user_input": ":account_id", + "confidence": "High", + "cwe_id": [ + 915 + ], + "note": "" + }, { "warning_type": "Cross-Site Scripting", "warning_code": 4, @@ -89,8 +135,54 @@ 79 ], "note": "" + }, + { + "warning_type": "Mass Assignment", + "warning_code": 105, + "fingerprint": "d0511f0287aea4ed9511f5a744f880cb15af77a8ec88f81b7365b00b642cf427", + "check_name": "PermitAttributes", + "message": "Potentially dangerous key allowed for mass assignment", + "file": "app/controllers/api/v1/reports_controller.rb", + "line": 26, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit(:account_id, :comment, :category, :forward, :forward_to_domains => ([]), :status_ids => ([]), :rule_ids => ([]))", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V1::ReportsController", + "method": "report_params" + }, + "user_input": ":account_id", + "confidence": "High", + "cwe_id": [ + 915 + ], + "note": "" + }, + { + "warning_type": "Mass Assignment", + "warning_code": 105, + "fingerprint": "dd59382eb5fda8da4d29f5d52dc8261ed9070d3c61cecc12b8332e18448b1c11", + "check_name": "PermitAttributes", + "message": "Potentially dangerous key allowed for mass assignment", + "file": "app/controllers/api/v2/search_controller.rb", + "line": 42, + "link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/", + "code": "params.permit(:type, :offset, :min_id, :max_id, :account_id, :following, :searchability)", + "render_path": null, + "location": { + "type": "method", + "class": "Api::V2::SearchController", + "method": "search_params" + }, + "user_input": ":account_id", + "confidence": "High", + "cwe_id": [ + 915 + ], + "note": "" } ], - "updated": "2023-07-12 11:20:51 -0400", - "brakeman_version": "6.0.0" + "updated": "2023-07-30 22:53:30 +0900", + "brakeman_version": "6.0.1" } diff --git a/config/sidekiq.yml b/config/sidekiq.yml index fdd1d73e1b..abd90944cf 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -62,3 +62,7 @@ interval: 30 seconds class: Scheduler::SidekiqHealthScheduler queue: scheduler + update_instance_info_scheduler: + cron: '0 0 * * *' + class: Scheduler::UpdateInstanceInfoScheduler + queue: scheduler diff --git a/db/migrate/20230308061833_add_image_size_to_custom_emojis.rb b/db/migrate/20230308061833_add_image_size_to_custom_emojis.rb index bca687b0af..02655ebff4 100644 --- a/db/migrate/20230308061833_add_image_size_to_custom_emojis.rb +++ b/db/migrate/20230308061833_add_image_size_to_custom_emojis.rb @@ -2,16 +2,20 @@ class AddImageSizeToCustomEmojis < ActiveRecord::Migration[6.1] def change - change_table :custom_emojis, bulk: true do |t| - t.integer :image_width - t.integer :image_height + safety_assured do + change_table :custom_emojis, bulk: true do |t| + t.integer :image_width + t.integer :image_height + end end end def down - change_table :custom_emojis, bulk: true do |t| - t.remove :image_width - t.remove :image_height + safety_assured do + change_table :custom_emojis, bulk: true do |t| + t.remove :image_width + t.remove :image_height + end end end end diff --git a/db/migrate/20230405121625_add_searchability_to_accounts.rb b/db/migrate/20230405121625_add_searchability_to_accounts.rb index c68f987761..e1b7a216e4 100644 --- a/db/migrate/20230405121625_add_searchability_to_accounts.rb +++ b/db/migrate/20230405121625_add_searchability_to_accounts.rb @@ -2,6 +2,8 @@ class AddSearchabilityToAccounts < ActiveRecord::Migration[6.1] def change - add_column :accounts, :searchability, :integer, null: false, default: 0 + safety_assured do + add_column :accounts, :searchability, :integer, null: false, default: 0 + end end end diff --git a/db/migrate/20230410004651_add_emoji_reactions_count_to_status_stats.rb b/db/migrate/20230410004651_add_emoji_reactions_count_to_status_stats.rb index f6e33ad286..71231c37b2 100644 --- a/db/migrate/20230410004651_add_emoji_reactions_count_to_status_stats.rb +++ b/db/migrate/20230410004651_add_emoji_reactions_count_to_status_stats.rb @@ -2,6 +2,8 @@ class AddEmojiReactionsCountToStatusStats < ActiveRecord::Migration[6.1] def change - add_column :status_stats, :emoji_reactions_count, :integer, null: false, default: 0 + safety_assured do + add_column :status_stats, :emoji_reactions_count, :integer, null: false, default: 0 + end end end diff --git a/db/migrate/20230412005311_add_markdown_to_statuses.rb b/db/migrate/20230412005311_add_markdown_to_statuses.rb index 02c8295314..a9730796e5 100644 --- a/db/migrate/20230412005311_add_markdown_to_statuses.rb +++ b/db/migrate/20230412005311_add_markdown_to_statuses.rb @@ -2,6 +2,8 @@ class AddMarkdownToStatuses < ActiveRecord::Migration[6.1] def change - add_column :statuses, :markdown, :boolean, default: false + safety_assured do + add_column :statuses, :markdown, :boolean, default: false + end end end diff --git a/db/migrate/20230412073021_add_markdown_to_status_edits.rb b/db/migrate/20230412073021_add_markdown_to_status_edits.rb index b812cd080f..8dd5711487 100644 --- a/db/migrate/20230412073021_add_markdown_to_status_edits.rb +++ b/db/migrate/20230412073021_add_markdown_to_status_edits.rb @@ -2,6 +2,8 @@ class AddMarkdownToStatusEdits < ActiveRecord::Migration[6.1] def change - add_column :status_edits, :markdown, :boolean, default: false + safety_assured do + add_column :status_edits, :markdown, :boolean, default: false + end end end diff --git a/db/migrate/20230414010523_add_emoji_reactions_count_per_account_to_status_stats.rb b/db/migrate/20230414010523_add_emoji_reactions_count_per_account_to_status_stats.rb index f16f4d2f07..1725a7515e 100644 --- a/db/migrate/20230414010523_add_emoji_reactions_count_per_account_to_status_stats.rb +++ b/db/migrate/20230414010523_add_emoji_reactions_count_per_account_to_status_stats.rb @@ -2,6 +2,8 @@ class AddEmojiReactionsCountPerAccountToStatusStats < ActiveRecord::Migration[6.1] def change - add_column :status_stats, :emoji_reaction_accounts_count, :integer, null: false, default: 0 + safety_assured do + add_column :status_stats, :emoji_reaction_accounts_count, :integer, null: false, default: 0 + end end end diff --git a/db/migrate/20230426013738_add_excludes_to_antennas.rb b/db/migrate/20230426013738_add_excludes_to_antennas.rb index 18b93ce23b..33a7d16874 100644 --- a/db/migrate/20230426013738_add_excludes_to_antennas.rb +++ b/db/migrate/20230426013738_add_excludes_to_antennas.rb @@ -2,18 +2,22 @@ class AddExcludesToAntennas < ActiveRecord::Migration[6.1] def change - change_table :antennas, bulk: true do |t| - t.jsonb :exclude_domains - t.jsonb :exclude_accounts - t.jsonb :exclude_tags + safety_assured do + change_table :antennas, bulk: true do |t| + t.jsonb :exclude_domains + t.jsonb :exclude_accounts + t.jsonb :exclude_tags + end end end def down - change_table :antennas, bulk: true do |t| - t.remove :exclude_domains - t.remove :exclude_accounts - t.remove :exclude_tags + safety_assured do + change_table :antennas, bulk: true do |t| + t.remove :exclude_domains + t.remove :exclude_accounts + t.remove :exclude_tags + end end end end diff --git a/db/migrate/20230427072650_add_reject_sending_to_domain_blocks.rb b/db/migrate/20230427072650_add_reject_sending_to_domain_blocks.rb index 23ca84a7e7..fbb398edf1 100644 --- a/db/migrate/20230427072650_add_reject_sending_to_domain_blocks.rb +++ b/db/migrate/20230427072650_add_reject_sending_to_domain_blocks.rb @@ -2,24 +2,28 @@ class AddRejectSendingToDomainBlocks < ActiveRecord::Migration[6.1] def change - change_table :domain_blocks, bulk: true do |t| - t.boolean :reject_send_not_public_searchability, null: false, default: false - t.boolean :reject_send_unlisted_dissubscribable, null: false, default: false - t.boolean :reject_send_public_unlisted, null: false, default: false - t.boolean :reject_send_dissubscribable, null: false, default: false - t.boolean :reject_send_media, null: false, default: false - t.boolean :reject_send_sensitive, null: false, default: false + safety_assured do + change_table :domain_blocks, bulk: true do |t| + t.boolean :reject_send_not_public_searchability, null: false, default: false + t.boolean :reject_send_unlisted_dissubscribable, null: false, default: false + t.boolean :reject_send_public_unlisted, null: false, default: false + t.boolean :reject_send_dissubscribable, null: false, default: false + t.boolean :reject_send_media, null: false, default: false + t.boolean :reject_send_sensitive, null: false, default: false + end end end def down - change_table :domain_blocks, bulk: true do |t| - t.remove :reject_send_not_public_searchability - t.remove :reject_send_unlisted_dissubscribable - t.remove :reject_send_public_unlisted - t.remove :reject_send_dissubscribable - t.remove :reject_send_media - t.remove :reject_send_sensitive + safety_assured do + change_table :domain_blocks, bulk: true do |t| + t.remove :reject_send_not_public_searchability + t.remove :reject_send_unlisted_dissubscribable + t.remove :reject_send_public_unlisted + t.remove :reject_send_dissubscribable + t.remove :reject_send_media + t.remove :reject_send_sensitive + end end end end diff --git a/db/migrate/20230427122753_add_some_to_domain_blocks.rb b/db/migrate/20230427122753_add_some_to_domain_blocks.rb index a545094036..ca2a1876a6 100644 --- a/db/migrate/20230427122753_add_some_to_domain_blocks.rb +++ b/db/migrate/20230427122753_add_some_to_domain_blocks.rb @@ -2,18 +2,22 @@ class AddSomeToDomainBlocks < ActiveRecord::Migration[6.1] def change - change_table :domain_blocks, bulk: true do |t| - t.boolean :reject_hashtag, null: false, default: false - t.boolean :reject_straight_follow, null: false, default: false - t.boolean :reject_new_follow, null: false, default: false + safety_assured do + change_table :domain_blocks, bulk: true do |t| + t.boolean :reject_hashtag, null: false, default: false + t.boolean :reject_straight_follow, null: false, default: false + t.boolean :reject_new_follow, null: false, default: false + end end end def down - change_table :domain_blocks, bulk: true do |t| - t.remove :reject_hashtag - t.remove :reject_straight_follow - t.remove :reject_new_follow + safety_assured do + change_table :domain_blocks, bulk: true do |t| + t.remove :reject_hashtag + t.remove :reject_straight_follow + t.remove :reject_new_follow + end end end end diff --git a/db/migrate/20230427233749_add_hidden_to_domain_blocks.rb b/db/migrate/20230427233749_add_hidden_to_domain_blocks.rb index f467ae4b67..37511b314f 100644 --- a/db/migrate/20230427233749_add_hidden_to_domain_blocks.rb +++ b/db/migrate/20230427233749_add_hidden_to_domain_blocks.rb @@ -2,16 +2,20 @@ class AddHiddenToDomainBlocks < ActiveRecord::Migration[6.1] def change - change_table :domain_blocks, bulk: true do |t| - t.boolean :hidden, null: false, default: false - t.boolean :hidden_anonymous, null: false, default: false + safety_assured do + change_table :domain_blocks, bulk: true do |t| + t.boolean :hidden, null: false, default: false + t.boolean :hidden_anonymous, null: false, default: false + end end end def down - change_table :domain_blocks, bulk: true do |t| - t.remove :hidden - t.remove :hidden_anonymous + safety_assured do + change_table :domain_blocks, bulk: true do |t| + t.remove :hidden + t.remove :hidden_anonymous + end end end end diff --git a/db/migrate/20230428111230_add_emoji_reaction_streaming_to_accounts.rb b/db/migrate/20230428111230_add_emoji_reaction_streaming_to_accounts.rb index c5f6e3a4b0..43c7df805d 100644 --- a/db/migrate/20230428111230_add_emoji_reaction_streaming_to_accounts.rb +++ b/db/migrate/20230428111230_add_emoji_reaction_streaming_to_accounts.rb @@ -2,6 +2,8 @@ class AddEmojiReactionStreamingToAccounts < ActiveRecord::Migration[6.1] def change - add_column :accounts, :stop_emoji_reaction_streaming, :boolean, default: false + safety_assured do + add_column :accounts, :stop_emoji_reaction_streaming, :boolean, default: false + end end end diff --git a/db/migrate/20230430110057_add_reject_invalid_subscription_to_domain_blocks.rb b/db/migrate/20230430110057_add_reject_invalid_subscription_to_domain_blocks.rb index 86d87003b0..cf63d2f25e 100644 --- a/db/migrate/20230430110057_add_reject_invalid_subscription_to_domain_blocks.rb +++ b/db/migrate/20230430110057_add_reject_invalid_subscription_to_domain_blocks.rb @@ -1,10 +1,23 @@ # frozen_string_literal: true class AddRejectInvalidSubscriptionToDomainBlocks < ActiveRecord::Migration[6.1] - def change + def up safety_assured do - remove_column :domain_blocks, :reject_send_unlisted_dissubscribable, :boolean, null: false, default: false + remove_column :domain_blocks, :reject_send_unlisted_dissubscribable + + change_table :domain_blocks do |t| + t.boolean :detect_invalid_subscription, null: false, default: false + end + end + end + + def down + safety_assured do + remove_column :domain_blocks, :detect_invalid_subscription + + change_table :domain_blocks do |t| + t.boolean :reject_send_unlisted_dissubscribable, null: false, default: false + end end - add_column :domain_blocks, :detect_invalid_subscription, :boolean, null: false, default: false end end diff --git a/db/migrate/20230512122757_add_reject_reply_exclude_followers_to_domain_blocks.rb b/db/migrate/20230512122757_add_reject_reply_exclude_followers_to_domain_blocks.rb index 4bce446d63..22e6787917 100644 --- a/db/migrate/20230512122757_add_reject_reply_exclude_followers_to_domain_blocks.rb +++ b/db/migrate/20230512122757_add_reject_reply_exclude_followers_to_domain_blocks.rb @@ -2,6 +2,10 @@ class AddRejectReplyExcludeFollowersToDomainBlocks < ActiveRecord::Migration[6.1] def change - add_column :domain_blocks, :reject_reply_exclude_followers, :boolean, null: false, default: false + safety_assured do + change_table :domain_blocks do |t| + t.boolean :reject_reply_exclude_followers, null: false, default: false + end + end end end diff --git a/db/migrate/20230522082252_add_is_sensitive_to_custom_emojis.rb b/db/migrate/20230522082252_add_is_sensitive_to_custom_emojis.rb index 12666eec39..683133de4b 100644 --- a/db/migrate/20230522082252_add_is_sensitive_to_custom_emojis.rb +++ b/db/migrate/20230522082252_add_is_sensitive_to_custom_emojis.rb @@ -2,6 +2,10 @@ class AddIsSensitiveToCustomEmojis < ActiveRecord::Migration[6.1] def change - add_column :custom_emojis, :is_sensitive, :boolean, null: false, default: false + safety_assured do + change_table :custom_emojis do |t| + t.boolean :is_sensitive, null: false, default: false + end + end end end diff --git a/db/migrate/20230804222017_create_instance_infoes.rb b/db/migrate/20230804222017_create_instance_infoes.rb new file mode 100644 index 0000000000..c1d1ccbdc9 --- /dev/null +++ b/db/migrate/20230804222017_create_instance_infoes.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CreateInstanceInfoes < ActiveRecord::Migration[7.0] + def change + create_table :instance_infos do |t| + t.string :domain, null: false, default: '', index: { unique: true } + t.string :software, null: false, default: '' + t.string :version, null: false, default: '' + t.jsonb :data, null: false, default: {} + t.datetime :created_at, null: false + t.datetime :updated_at, null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a763d08f09..d3ac065448 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[7.0].define(version: 2023_07_24_160715) do +ActiveRecord::Schema[7.0].define(version: 2023_08_04_222017) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -631,6 +631,16 @@ ActiveRecord::Schema[7.0].define(version: 2023_07_24_160715) do t.boolean "overwrite", default: false, null: false end + create_table "instance_infos", force: :cascade do |t| + t.string "domain", default: "", null: false + t.string "software", default: "", null: false + t.string "version", default: "", null: false + t.jsonb "data", default: {}, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["domain"], name: "index_instance_infos_on_domain", unique: true + end + create_table "invites", force: :cascade do |t| t.bigint "user_id", null: false t.string "code", default: "", null: false diff --git a/spec/lib/emoji_formatter_spec.rb b/spec/lib/emoji_formatter_spec.rb index e5accfbb0c..ede75c77b0 100644 --- a/spec/lib/emoji_formatter_spec.rb +++ b/spec/lib/emoji_formatter_spec.rb @@ -26,7 +26,7 @@ RSpec.describe EmojiFormatter do let(:text) { preformat_text(':coolcat: Beep boop') } it 'converts the shortcode to an image tag' do - expect(subject).to match(/