Merge commit 'acdd0b33a3183569a2cdb50befdbba58f1e74ae9' into glitch-soc/merge-upstream

This commit is contained in:
Claire
2026-02-05 17:57:46 +01:00
9 changed files with 106 additions and 130 deletions

View File

@@ -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

View File

@@ -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}

View File

@@ -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,

View 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 }
>;

View File

@@ -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],

View File

@@ -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

View File

@@ -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.

View File

@@ -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

View File

@@ -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