mirror of
https://github.com/glitch-soc/mastodon.git
synced 2026-03-29 03:00:33 +02:00
Merge commit 'acdd0b33a3183569a2cdb50befdbba58f1e74ae9' into glitch-soc/merge-upstream
This commit is contained in:
@@ -472,9 +472,8 @@ GEM
|
||||
nokogiri (1.19.0)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
oj (3.16.13)
|
||||
oj (3.16.14)
|
||||
bigdecimal (>= 3.0)
|
||||
ostruct (>= 0.2)
|
||||
omniauth (2.1.4)
|
||||
hashie (>= 3.4.6)
|
||||
logger
|
||||
|
||||
@@ -140,6 +140,7 @@ class Status extends ImmutablePureComponent {
|
||||
'hidden',
|
||||
'unread',
|
||||
'pictureInPicture',
|
||||
'headerRenderFn',
|
||||
];
|
||||
|
||||
state = {
|
||||
@@ -556,7 +557,7 @@ class Status extends ImmutablePureComponent {
|
||||
const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status);
|
||||
|
||||
const header = this.props.headerRenderFn
|
||||
? this.props.headerRenderFn({ status, account, avatarSize, messages, onHeaderClick: this.handleHeaderClick })
|
||||
? this.props.headerRenderFn({ status, account, avatarSize, messages, onHeaderClick: this.handleHeaderClick, statusProps: this.props })
|
||||
: (
|
||||
<StatusHeader
|
||||
status={status}
|
||||
|
||||
@@ -15,6 +15,8 @@ import { LinkedDisplayName } from '../display_name';
|
||||
import { RelativeTimestamp } from '../relative_timestamp';
|
||||
import { VisibilityIcon } from '../visibility_icon';
|
||||
|
||||
import type { StatusProps } from './types';
|
||||
|
||||
export interface StatusHeaderProps {
|
||||
status: Status;
|
||||
account?: Account;
|
||||
@@ -25,7 +27,10 @@ export interface StatusHeaderProps {
|
||||
onHeaderClick?: MouseEventHandler<HTMLDivElement>;
|
||||
}
|
||||
|
||||
export type StatusHeaderRenderFn = (args: StatusHeaderProps) => ReactNode;
|
||||
export type StatusHeaderRenderFn = (
|
||||
args: StatusHeaderProps,
|
||||
statusProps?: StatusProps,
|
||||
) => ReactNode;
|
||||
|
||||
export const StatusHeader: FC<StatusHeaderProps> = ({
|
||||
status,
|
||||
|
||||
36
app/javascript/mastodon/components/status/types.ts
Normal file
36
app/javascript/mastodon/components/status/types.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { ComponentClass, MouseEventHandler, ReactNode } from 'react';
|
||||
|
||||
import type { Account } from '@/mastodon/models/account';
|
||||
|
||||
import type { StatusHeaderRenderFn } from './header';
|
||||
|
||||
// Taken from the Status component.
|
||||
export interface StatusProps {
|
||||
account?: Account;
|
||||
children?: ReactNode;
|
||||
previousId?: string;
|
||||
rootId?: string;
|
||||
onClick?: MouseEventHandler<HTMLDivElement>;
|
||||
muted?: boolean;
|
||||
hidden?: boolean;
|
||||
unread?: boolean;
|
||||
showThread?: boolean;
|
||||
showActions?: boolean;
|
||||
isQuotedPost?: boolean;
|
||||
shouldHighlightOnMount?: boolean;
|
||||
getScrollPosition?: () => null | { height: number; top: number };
|
||||
updateScrollBottom?: (snapshot: number) => void;
|
||||
cacheMediaWidth?: (width: number) => void;
|
||||
cachedMediaWidth?: number;
|
||||
scrollKey?: string;
|
||||
skipPrepend?: boolean;
|
||||
avatarSize?: number;
|
||||
unfocusable?: boolean;
|
||||
headerRenderFn?: StatusHeaderRenderFn;
|
||||
contextType?: string;
|
||||
}
|
||||
|
||||
export type StatusComponent = ComponentClass<
|
||||
StatusProps,
|
||||
{ showMedia?: boolean; showDespiteFilter?: boolean }
|
||||
>;
|
||||
@@ -226,13 +226,15 @@ export const QuotedStatus: React.FC<QuotedStatusProps> = ({
|
||||
const headerRenderFn: StatusHeaderRenderFn = useCallback(
|
||||
(props) => (
|
||||
<StatusHeader {...props}>
|
||||
<IconButton
|
||||
onClick={onQuoteCancel}
|
||||
className='status__quote-cancel'
|
||||
title={intl.formatMessage(quoteCancelMessage)}
|
||||
icon='cancel-fill'
|
||||
iconComponent={CancelFillIcon}
|
||||
/>
|
||||
{onQuoteCancel && (
|
||||
<IconButton
|
||||
onClick={onQuoteCancel}
|
||||
className='status__quote-cancel'
|
||||
title={intl.formatMessage(quoteCancelMessage)}
|
||||
icon='cancel-fill'
|
||||
iconComponent={CancelFillIcon}
|
||||
/>
|
||||
)}
|
||||
</StatusHeader>
|
||||
),
|
||||
[intl, onQuoteCancel],
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
class AfterUnallowDomainService < BaseService
|
||||
def call(domain)
|
||||
Account.where(domain: domain).find_each do |account|
|
||||
return if domain.blank?
|
||||
|
||||
Account.remote.where(domain: domain).find_each do |account|
|
||||
DeleteAccountService.new.call(account, reserve_username: false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,9 +5,7 @@ require 'active_support/core_ext/integer/time'
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# In the development environment your application's code is reloaded any time
|
||||
# it changes. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
# Make code changes take effect immediately without server restart.
|
||||
config.enable_reloading = true
|
||||
|
||||
# Do not eager load code on boot.
|
||||
@@ -22,8 +20,8 @@ Rails.application.configure do
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
config.asset_host = ENV['CDN_HOST'] if ENV['CDN_HOST'].present?
|
||||
|
||||
# Enable/disable caching. By default caching is disabled.
|
||||
# Run rails dev:cache to toggle caching.
|
||||
# Enable/disable Action Controller caching. By default Action Controller caching is disabled.
|
||||
# Run rails dev:cache to toggle Action Controller caching.
|
||||
if Rails.root.join('tmp', 'caching-dev.txt').exist?
|
||||
config.action_controller.perform_caching = true
|
||||
config.action_controller.enable_fragment_cache_logging = true
|
||||
@@ -34,7 +32,6 @@ Rails.application.configure do
|
||||
}
|
||||
else
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
config.cache_store = :null_store
|
||||
end
|
||||
|
||||
@@ -52,8 +49,7 @@ Rails.application.configure do
|
||||
# Don't care if the mailer can't send.
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Disable caching for Action Mailer templates even if Action Controller
|
||||
# caching is enabled.
|
||||
# Make template changes take effect immediately.
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Print deprecation notices to the Rails logger.
|
||||
|
||||
@@ -8,26 +8,16 @@ Rails.application.configure do
|
||||
# Code is not reloaded between requests.
|
||||
config.enable_reloading = false
|
||||
|
||||
# Eager load code on boot. This eager loads most of Rails and
|
||||
# your application in memory, allowing both threaded web servers
|
||||
# and those relying on copy on write to perform better.
|
||||
# Rake tasks automatically ignore this option for performance.
|
||||
# Eager load code on boot for better performance and memory savings (ignored by Rake tasks).
|
||||
config.eager_load = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on.
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
|
||||
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
|
||||
# config.require_master_key = true
|
||||
|
||||
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
||||
config.assets.compile = false
|
||||
|
||||
# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
|
||||
# config.public_file_server.enabled = false
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
config.asset_host = ENV['CDN_HOST'] if ENV['CDN_HOST'].present?
|
||||
|
||||
@@ -40,11 +30,11 @@ Rails.application.configure do
|
||||
config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split(/(?:\s*,\s*|\s+)/).map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present?
|
||||
|
||||
# Assume all access to the app is happening through a SSL-terminating reverse proxy.
|
||||
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
|
||||
# config.assume_ssl = true
|
||||
|
||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
config.force_ssl = true
|
||||
|
||||
# Skip http-to-https redirect for the default health check endpoint.
|
||||
config.ssl_options = {
|
||||
redirect: {
|
||||
@@ -59,31 +49,16 @@ Rails.application.configure do
|
||||
config.log_tags = [:request_id]
|
||||
config.logger = ActiveSupport::TaggedLogging.logger($stdout, formatter: config.log_formatter)
|
||||
|
||||
# Change to "debug" to log everything (including potentially personally-identifiable information!)
|
||||
# Change to "debug" to log everything (including potentially personally-identifiable information!).
|
||||
config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info')
|
||||
|
||||
# Use a different cache store in production.
|
||||
config.cache_store = :redis_cache_store, REDIS_CONFIGURATION.cache
|
||||
|
||||
# Use a real queuing backend for Active Job (and separate queues per environment).
|
||||
# config.active_job.queue_adapter = :resque
|
||||
# config.active_job.queue_name_prefix = "mastodon_production"
|
||||
|
||||
# Disable caching for Action Mailer templates even if Action Controller
|
||||
# caching is enabled.
|
||||
config.action_mailer.perform_caching = false
|
||||
|
||||
# Ignore bad email addresses and do not raise email delivery errors.
|
||||
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
||||
# config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# the I18n.default_locale when a translation cannot be found).
|
||||
# This setting would typically be `true` to use the `I18n.default_locale`.
|
||||
# Some locales are missing translation entries and would have errors:
|
||||
# https://github.com/mastodon/mastodon/pull/24727
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Don't log any deprecations.
|
||||
config.active_support.report_deprecations = false
|
||||
|
||||
@@ -94,6 +69,13 @@ Rails.application.configure do
|
||||
{ key: controller.signature_key_id } if controller.respond_to?(:signed_request?) && controller.signed_request?
|
||||
end
|
||||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# the I18n.default_locale when a translation cannot be found).
|
||||
# This setting would typically be `true` to use the `I18n.default_locale`.
|
||||
# Some locales are missing translation entries and would have errors:
|
||||
# https://github.com/mastodon/mastodon/pull/24727
|
||||
config.i18n.fallbacks = [:en]
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
config.action_mailer.perform_caching = false
|
||||
@@ -128,6 +110,7 @@ Rails.application.configure do
|
||||
# "example.com", # Allow requests from example.com
|
||||
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
|
||||
# ]
|
||||
#
|
||||
# Skip DNS rebinding protection for the default health check endpoint.
|
||||
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
|
||||
end
|
||||
|
||||
@@ -3,73 +3,45 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe DomainValidator do
|
||||
let(:record) { record_class.new }
|
||||
subject { record_class.new }
|
||||
|
||||
context 'with no options' do
|
||||
let(:record_class) do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
||||
def self.name = 'Record'
|
||||
|
||||
attr_accessor :domain
|
||||
|
||||
validates :domain, domain: true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#validate_each' do
|
||||
context 'with a nil value' do
|
||||
it 'does not add errors' do
|
||||
record.domain = nil
|
||||
context 'with a nil value' do
|
||||
it { is_expected.to allow_value(nil).for(:domain) }
|
||||
end
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
context 'with a valid domain' do
|
||||
it { is_expected.to allow_value('host.example').for(:domain) }
|
||||
end
|
||||
|
||||
context 'with a valid domain' do
|
||||
it 'does not add errors' do
|
||||
record.domain = 'example.com'
|
||||
context 'with a domain that is too long' do
|
||||
let(:long_hostname) { "#{'a' * 300}.com" }
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
it { is_expected.to_not allow_value(long_hostname).for(:domain) }
|
||||
end
|
||||
|
||||
context 'with a domain that is too long' do
|
||||
it 'adds an error' do
|
||||
record.domain = "#{'a' * 300}.com"
|
||||
context 'with a domain with an empty segment' do
|
||||
it { is_expected.to_not allow_value('.example.com').for(:domain) }
|
||||
end
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
context 'with a domain with an invalid character' do
|
||||
it { is_expected.to_not allow_value('*.example.com').for(:domain) }
|
||||
end
|
||||
|
||||
context 'with a domain with an empty segment' do
|
||||
it 'adds an error' do
|
||||
record.domain = '.example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a domain with an invalid character' do
|
||||
it 'adds an error' do
|
||||
record.domain = '*.example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a domain that would fail parsing' do
|
||||
it 'adds an error' do
|
||||
record.domain = '/'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:domain)).to_not be_empty
|
||||
end
|
||||
end
|
||||
context 'with a domain that would fail parsing' do
|
||||
it { is_expected.to_not allow_value('/').for(:domain) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -78,48 +50,28 @@ RSpec.describe DomainValidator do
|
||||
Class.new do
|
||||
include ActiveModel::Validations
|
||||
|
||||
def self.name = 'Record'
|
||||
|
||||
attr_accessor :acct
|
||||
|
||||
validates :acct, domain: { acct: true }
|
||||
end
|
||||
end
|
||||
|
||||
describe '#validate_each' do
|
||||
context 'with a nil value' do
|
||||
it 'does not add errors' do
|
||||
record.acct = nil
|
||||
context 'with a nil value' do
|
||||
it { is_expected.to allow_value(nil).for(:acct) }
|
||||
end
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
context 'with no domain' do
|
||||
it { is_expected.to allow_value('hoge_123').for(:acct) }
|
||||
end
|
||||
|
||||
context 'with no domain' do
|
||||
it 'does not add errors' do
|
||||
record.acct = 'hoge_123'
|
||||
context 'with a valid domain' do
|
||||
it { is_expected.to allow_value('hoge_123@example.com').for(:acct) }
|
||||
end
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a valid domain' do
|
||||
it 'does not add errors' do
|
||||
record.acct = 'hoge_123@example.com'
|
||||
|
||||
expect(record).to be_valid
|
||||
expect(record.errors).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an invalid domain' do
|
||||
it 'adds an error' do
|
||||
record.acct = 'hoge_123@.example.com'
|
||||
|
||||
expect(record).to_not be_valid
|
||||
expect(record.errors.where(:acct)).to_not be_empty
|
||||
end
|
||||
end
|
||||
context 'with an invalid domain' do
|
||||
it { is_expected.to_not allow_value('hoge_123@.example.com').for(:acct) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user