mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 00:08:46 +00:00
Merge pull request #3126 from ClearlyClaire/glitch-soc/merge-4.4
Merge upstream changes up to 609a40181e
This commit is contained in:
10
CHANGELOG.md
10
CHANGELOG.md
@@ -2,6 +2,16 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [4.4.1] - 2025-07-09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix nearly every sub-directory being crawled as part of Vite build (#35323 by @ClearlyClaire)
|
||||||
|
- Fix assets not building when Redis is unavailable (#35321 by @oneiros)
|
||||||
|
- Fix replying from media modal or pop-in-player tagging user `@undefined` (#35317 by @ClearlyClaire)
|
||||||
|
- Fix support for special characters in various environment variables (#35314 by @mjankowski and @ClearlyClaire)
|
||||||
|
- Fix some database migrations failing for indexes manually removed by admins (#35309 by @mjankowski)
|
||||||
|
|
||||||
## [4.4.0] - 2025-07-08
|
## [4.4.0] - 2025-07-08
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
|
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
@@ -21,6 +21,9 @@ import { openModal } from 'mastodon/actions/modal';
|
|||||||
import { IconButton } from 'mastodon/components/icon_button';
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
import { useIdentity } from 'mastodon/identity_context';
|
import { useIdentity } from 'mastodon/identity_context';
|
||||||
import { me } from 'mastodon/initial_state';
|
import { me } from 'mastodon/initial_state';
|
||||||
|
import type { Status } from 'mastodon/models/status';
|
||||||
|
import { makeGetStatus } from 'mastodon/selectors';
|
||||||
|
import type { RootState } from 'mastodon/store';
|
||||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
@@ -47,6 +50,11 @@ const messages = defineMessages({
|
|||||||
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
open: { id: 'status.open', defaultMessage: 'Expand this status' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type GetStatusSelector = (
|
||||||
|
state: RootState,
|
||||||
|
props: { id?: string | null; contextType?: string },
|
||||||
|
) => Status | null;
|
||||||
|
|
||||||
export const Footer: React.FC<{
|
export const Footer: React.FC<{
|
||||||
statusId: string;
|
statusId: string;
|
||||||
withOpenButton?: boolean;
|
withOpenButton?: boolean;
|
||||||
@@ -56,7 +64,8 @@ export const Footer: React.FC<{
|
|||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const status = useAppSelector((state) => state.statuses.get(statusId));
|
const getStatus = useMemo(() => makeGetStatus(), []) as GetStatusSelector;
|
||||||
|
const status = useAppSelector((state) => getStatus(state, { id: statusId }));
|
||||||
const accountId = status?.get('account') as string | undefined;
|
const accountId = status?.get('account') as string | undefined;
|
||||||
const account = useAppSelector((state) =>
|
const account = useAppSelector((state) =>
|
||||||
accountId ? state.accounts.get(accountId) : undefined,
|
accountId ? state.accounts.get(accountId) : undefined,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
shared:
|
shared:
|
||||||
enabled: <%= ENV.fetch('CACHE_BUSTER_ENABLED', 'false') == 'true' %>
|
enabled: <%= ENV.fetch('CACHE_BUSTER_ENABLED', 'false') == 'true' %>
|
||||||
secret_header: <%= ENV.fetch('CACHE_BUSTER_SECRET_HEADER', nil) %>
|
secret_header: <%= ENV.fetch('CACHE_BUSTER_SECRET_HEADER', nil)&.to_json %>
|
||||||
secret: <%= ENV.fetch('CACHE_BUSTER_SECRET', nil) %>
|
secret: <%= ENV.fetch('CACHE_BUSTER_SECRET', nil)&.to_json %>
|
||||||
http_method: <%= ENV.fetch('CACHE_BUSTER_HTTP_METHOD', 'GET') %>
|
http_method: <%= ENV.fetch('CACHE_BUSTER_HTTP_METHOD', 'GET') %>
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
# keys are added here.
|
# keys are added here.
|
||||||
production:
|
production:
|
||||||
delivery_method: <%= ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp') %>
|
delivery_method: <%= ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp') %>
|
||||||
from_address: <%= ENV.fetch('SMTP_FROM_ADDRESS', 'notifications@localhost') %>
|
from_address: <%= ENV.fetch('SMTP_FROM_ADDRESS', 'notifications@localhost')&.to_json %>
|
||||||
reply_to: <%= ENV.fetch('SMTP_REPLY_TO', nil) %>
|
reply_to: <%= ENV.fetch('SMTP_REPLY_TO', nil)&.to_json %>
|
||||||
return_path: <%= ENV.fetch('SMTP_RETURN_PATH', nil) %>
|
return_path: <%= ENV.fetch('SMTP_RETURN_PATH', nil)&.to_json %>
|
||||||
smtp_settings:
|
smtp_settings:
|
||||||
port: <%= ENV.fetch('SMTP_PORT', nil) %>
|
port: <%= ENV.fetch('SMTP_PORT', nil) %>
|
||||||
address: <%= ENV.fetch('SMTP_SERVER', nil) %>
|
address: <%= ENV.fetch('SMTP_SERVER', nil)&.to_json %>
|
||||||
user_name: <%= ENV.fetch('SMTP_LOGIN', nil) %>
|
user_name: <%= ENV.fetch('SMTP_LOGIN', nil)&.to_json %>
|
||||||
password: <%= ENV.fetch('SMTP_PASSWORD', nil) %>
|
password: <%= ENV.fetch('SMTP_PASSWORD', nil)&.to_json %>
|
||||||
domain: <%= ENV.fetch('SMTP_DOMAIN', ENV.fetch('LOCAL_DOMAIN', nil)) %>
|
domain: <%= ENV.fetch('SMTP_DOMAIN', ENV.fetch('LOCAL_DOMAIN', nil)) %>
|
||||||
authentication: <%= ENV.fetch('SMTP_AUTH_METHOD', 'plain') %>
|
authentication: <%= ENV.fetch('SMTP_AUTH_METHOD', 'plain') %>
|
||||||
ca_file: <%= ENV.fetch('SMTP_CA_FILE', '/etc/ssl/certs/ca-certificates.crt') %>
|
ca_file: <%= ENV.fetch('SMTP_CA_FILE', '/etc/ssl/certs/ca-certificates.crt') %>
|
||||||
@@ -22,9 +22,9 @@ production:
|
|||||||
bulk_mail:
|
bulk_mail:
|
||||||
smtp_settings:
|
smtp_settings:
|
||||||
port: <%= ENV.fetch('BULK_SMTP_PORT', nil) %>
|
port: <%= ENV.fetch('BULK_SMTP_PORT', nil) %>
|
||||||
address: <%= ENV.fetch('BULK_SMTP_SERVER', nil) %>
|
address: <%= ENV.fetch('BULK_SMTP_SERVER', nil)&.to_json %>
|
||||||
user_name: <%= ENV.fetch('BULK_SMTP_LOGIN', nil) %>
|
user_name: <%= ENV.fetch('BULK_SMTP_LOGIN', nil)&.to_json %>
|
||||||
password: <%= ENV.fetch('BULK_SMTP_PASSWORD', nil) %>
|
password: <%= ENV.fetch('BULK_SMTP_PASSWORD', nil)&.to_json %>
|
||||||
domain: <%= ENV.fetch('BULK_SMTP_DOMAIN', ENV.fetch('LOCAL_DOMAIN', nil)) %>
|
domain: <%= ENV.fetch('BULK_SMTP_DOMAIN', ENV.fetch('LOCAL_DOMAIN', nil)) %>
|
||||||
authentication: <%= ENV.fetch('BULK_SMTP_AUTH_METHOD', 'plain') %>
|
authentication: <%= ENV.fetch('BULK_SMTP_AUTH_METHOD', 'plain') %>
|
||||||
ca_file: <%= ENV.fetch('BULK_SMTP_CA_FILE', '/etc/ssl/certs/ca-certificates.crt') %>
|
ca_file: <%= ENV.fetch('BULK_SMTP_CA_FILE', '/etc/ssl/certs/ca-certificates.crt') %>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
Rails.application.config.to_prepare do
|
Rails.application.config.to_prepare do
|
||||||
custom_css = begin
|
custom_css = begin
|
||||||
Setting.custom_css
|
Setting.custom_css
|
||||||
rescue ActiveRecord::AdapterError # Running without a database, not migrated, no connection, etc
|
rescue # Running without a cache, database, not migrated, no connection, etc
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
shared:
|
shared:
|
||||||
experimental_features: <%= ENV.fetch('EXPERIMENTAL_FEATURES', nil) %>
|
experimental_features: <%= ENV.fetch('EXPERIMENTAL_FEATURES', nil) %>
|
||||||
limited_federation_mode: <%= (ENV.fetch('LIMITED_FEDERATION_MODE', nil) || ENV.fetch('WHITELIST_MODE', nil)) == 'true' %>
|
limited_federation_mode: <%= (ENV.fetch('LIMITED_FEDERATION_MODE', nil) || ENV.fetch('WHITELIST_MODE', nil)) == 'true' %>
|
||||||
self_destruct_value: <%= ENV.fetch('SELF_DESTRUCT', nil) %>
|
self_destruct_value: <%= ENV.fetch('SELF_DESTRUCT', nil)&.to_json %>
|
||||||
software_update_url: <%= ENV.fetch('UPDATE_CHECK_URL', 'https://api.joinmastodon.org/update-check') %>
|
software_update_url: <%= ENV.fetch('UPDATE_CHECK_URL', 'https://api.joinmastodon.org/update-check')&.to_json %>
|
||||||
source:
|
source:
|
||||||
base_url: <%= ENV.fetch('SOURCE_BASE_URL', nil) %>
|
base_url: <%= ENV.fetch('SOURCE_BASE_URL', nil)&.to_json %>
|
||||||
repository: <%= ENV.fetch('GITHUB_REPOSITORY', 'glitch-soc/mastodon') %>
|
repository: <%= ENV.fetch('GITHUB_REPOSITORY', 'glitch-soc/mastodon') %>
|
||||||
tag: <%= ENV.fetch('SOURCE_TAG', nil) %>
|
tag: <%= ENV.fetch('SOURCE_TAG', nil) %>
|
||||||
version:
|
version:
|
||||||
metadata: <%= ['glitch', ENV.fetch('MASTODON_VERSION_METADATA', nil)].compact_blank.join('.') %>
|
metadata: <%= ['glitch', ENV.fetch('MASTODON_VERSION_METADATA', nil)].compact_blank.join('.')&.to_json %>
|
||||||
prerelease: <%= ENV.fetch('MASTODON_VERSION_PRERELEASE', nil) %>
|
prerelease: <%= ENV.fetch('MASTODON_VERSION_PRERELEASE', nil)&.to_json %>
|
||||||
test:
|
test:
|
||||||
experimental_features: <%= [ENV.fetch('EXPERIMENTAL_FEATURES', nil), 'testing_only'].compact.join(',') %>
|
experimental_features: <%= [ENV.fetch('EXPERIMENTAL_FEATURES', nil), 'testing_only'].compact.join(',') %>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
shared:
|
shared:
|
||||||
deepl:
|
deepl:
|
||||||
api_key: <%= ENV.fetch('DEEPL_API_KEY', nil) %>
|
api_key: <%= ENV.fetch('DEEPL_API_KEY', nil)&.to_json %>
|
||||||
plan: <%= ENV.fetch('DEEPL_PLAN', 'free') %>
|
plan: <%= ENV.fetch('DEEPL_PLAN', 'free') %>
|
||||||
libre_translate:
|
libre_translate:
|
||||||
api_key: <%= ENV.fetch('LIBRE_TRANSLATE_API_KEY', nil) %>
|
api_key: <%= ENV.fetch('LIBRE_TRANSLATE_API_KEY', nil)&.to_json %>
|
||||||
endpoint: <%= ENV.fetch('LIBRE_TRANSLATE_ENDPOINT', nil) %>
|
endpoint: <%= ENV.fetch('LIBRE_TRANSLATE_ENDPOINT', nil)&.to_json %>
|
||||||
|
|||||||
@@ -13,5 +13,5 @@
|
|||||||
# https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
# https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
||||||
#
|
#
|
||||||
shared:
|
shared:
|
||||||
private_key: <%= ENV.fetch('VAPID_PRIVATE_KEY', nil) %>
|
private_key: <%= ENV.fetch('VAPID_PRIVATE_KEY', nil)&.to_json %>
|
||||||
public_key: <%= ENV.fetch('VAPID_PUBLIC_KEY', nil) %>
|
public_key: <%= ENV.fetch('VAPID_PUBLIC_KEY', nil)&.to_json %>
|
||||||
|
|||||||
@@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
class RemoveDuplicateIndexes < ActiveRecord::Migration[7.1]
|
class RemoveDuplicateIndexes < ActiveRecord::Migration[7.1]
|
||||||
def change
|
def change
|
||||||
|
with_options if_exists: true do
|
||||||
remove_index :account_aliases, :account_id
|
remove_index :account_aliases, :account_id
|
||||||
remove_index :account_relationship_severance_events, :account_id
|
remove_index :account_relationship_severance_events, :account_id
|
||||||
remove_index :custom_filter_statuses, :status_id
|
remove_index :custom_filter_statuses, :status_id
|
||||||
remove_index :webauthn_credentials, :user_id
|
remove_index :webauthn_credentials, :user_id
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ services:
|
|||||||
web:
|
web:
|
||||||
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
||||||
# build: .
|
# build: .
|
||||||
image: ghcr.io/glitch-soc/mastodon:v4.4.0
|
image: ghcr.io/glitch-soc/mastodon:v4.4.1
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bundle exec puma -C config/puma.rb
|
command: bundle exec puma -C config/puma.rb
|
||||||
@@ -83,7 +83,7 @@ services:
|
|||||||
# build:
|
# build:
|
||||||
# dockerfile: ./streaming/Dockerfile
|
# dockerfile: ./streaming/Dockerfile
|
||||||
# context: .
|
# context: .
|
||||||
image: ghcr.io/glitch-soc/mastodon-streaming:v4.4.0
|
image: ghcr.io/glitch-soc/mastodon-streaming:v4.4.1
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: node ./streaming/index.js
|
command: node ./streaming/index.js
|
||||||
@@ -102,7 +102,7 @@ services:
|
|||||||
sidekiq:
|
sidekiq:
|
||||||
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
# You can uncomment the following line if you want to not use the prebuilt image, for example if you have local code changes
|
||||||
# build: .
|
# build: .
|
||||||
image: ghcr.io/glitch-soc/mastodon:v4.4.0
|
image: ghcr.io/glitch-soc/mastodon:v4.4.1
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bundle exec sidekiq
|
command: bundle exec sidekiq
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ module Mastodon
|
|||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
0
|
1
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_prerelease
|
def default_prerelease
|
||||||
|
|||||||
22
spec/configuration/email_spec.rb
Normal file
22
spec/configuration/email_spec.rb
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe 'Configuration for email', type: :feature do
|
||||||
|
context 'with special characters in SMTP_PASSWORD env variable' do
|
||||||
|
let(:password) { ']]123456789[["!:@<>/\\=' }
|
||||||
|
|
||||||
|
around do |example|
|
||||||
|
ClimateControl.modify SMTP_PASSWORD: password do
|
||||||
|
example.run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'parses value correctly' do
|
||||||
|
expect(Rails.application.config_for(:email, env: :production))
|
||||||
|
.to include(
|
||||||
|
smtp_settings: include(password: password)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -79,7 +79,7 @@ export const config: UserConfigFnPromise = async ({ mode, command }) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
tsconfigPaths(),
|
tsconfigPaths({ projects: [path.resolve(__dirname, 'tsconfig.json')] }),
|
||||||
RailsPlugin({
|
RailsPlugin({
|
||||||
compress: mode === 'production' && command === 'build',
|
compress: mode === 'production' && command === 'build',
|
||||||
sri: {
|
sri: {
|
||||||
|
|||||||
Reference in New Issue
Block a user