diff --git a/.browserslistrc b/.browserslistrc
index 54dd3aaf34..0376af4bcc 100644
--- a/.browserslistrc
+++ b/.browserslistrc
@@ -1,7 +1,9 @@
[production]
defaults
-not IE 11
+> 0.2%
+ios >= 15.6
not dead
+not OperaMini all
[development]
supports es6-module
diff --git a/.devcontainer/codespaces/devcontainer.json b/.devcontainer/codespaces/devcontainer.json
index b32e4026d2..ca9156fdaa 100644
--- a/.devcontainer/codespaces/devcontainer.json
+++ b/.devcontainer/codespaces/devcontainer.json
@@ -5,7 +5,7 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
- "ghcr.io/devcontainers/features/sshd:1": {},
+ "ghcr.io/devcontainers/features/sshd:1": {}
},
"runServices": ["app", "db", "redis"],
@@ -15,16 +15,16 @@
"portsAttributes": {
"3000": {
"label": "web",
- "onAutoForward": "notify",
+ "onAutoForward": "notify"
},
"4000": {
"label": "stream",
- "onAutoForward": "silent",
- },
+ "onAutoForward": "silent"
+ }
},
"otherPortsAttributes": {
- "onAutoForward": "silent",
+ "onAutoForward": "silent"
},
"remoteEnv": {
@@ -33,7 +33,7 @@
"STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev",
"DISABLE_FORGERY_REQUEST_PROTECTION": "true",
"ES_ENABLED": "",
- "LIBRE_TRANSLATE_ENDPOINT": "",
+ "LIBRE_TRANSLATE_ENDPOINT": ""
},
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
@@ -43,7 +43,7 @@
"customizations": {
"vscode": {
"settings": {},
- "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"],
- },
- },
+ "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
+ }
+ }
}
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index ed71235b3b..fa8d6542c1 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -5,7 +5,7 @@
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
- "ghcr.io/devcontainers/features/sshd:1": {},
+ "ghcr.io/devcontainers/features/sshd:1": {}
},
"forwardPorts": [3000, 4000],
@@ -14,17 +14,17 @@
"3000": {
"label": "web",
"onAutoForward": "notify",
- "requireLocalPort": true,
+ "requireLocalPort": true
},
"4000": {
"label": "stream",
"onAutoForward": "silent",
- "requireLocalPort": true,
- },
+ "requireLocalPort": true
+ }
},
"otherPortsAttributes": {
- "onAutoForward": "silent",
+ "onAutoForward": "silent"
},
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
@@ -34,7 +34,7 @@
"customizations": {
"vscode": {
"settings": {},
- "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"],
- },
- },
+ "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
+ }
+ }
}
diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml
index 88979723c3..d14af5d7d9 100644
--- a/.devcontainer/docker-compose.yml
+++ b/.devcontainer/docker-compose.yml
@@ -70,7 +70,7 @@ services:
hard: -1
libretranslate:
- image: libretranslate/libretranslate:v1.5.4
+ image: libretranslate/libretranslate:v1.5.6
restart: unless-stopped
volumes:
- lt-data:/home/libretranslate/.local
diff --git a/.eslintrc.js b/.eslintrc.js
index ba4c9c40b5..87a1af483b 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -123,7 +123,7 @@ module.exports = defineConfig({
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
'react/self-closing-comp': 'error',
- // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js
+ // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
'jsx-a11y/accessible-emoji': 'warn',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/label-has-associated-control': 'off',
@@ -165,7 +165,7 @@ module.exports = defineConfig({
// },
// ],
'jsx-a11y/no-noninteractive-tabindex': 'off',
- 'jsx-a11y/no-onchange': 'warn',
+ 'jsx-a11y/no-onchange': 'off',
// recommended is full 'error'
'jsx-a11y/no-static-element-interactions': [
'warn',
@@ -176,7 +176,7 @@ module.exports = defineConfig({
},
],
- // See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js
+ // See https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/config/recommended.js
'import/extensions': [
'error',
'always',
@@ -355,7 +355,6 @@ module.exports = defineConfig({
'plugin:import/typescript',
'plugin:promise/recommended',
'plugin:jsdoc/recommended-typescript',
- 'plugin:prettier/recommended',
],
parserOptions: {
@@ -364,6 +363,9 @@ module.exports = defineConfig({
},
rules: {
+ // Disable formatting rules that have been enabled in the base config
+ 'indent': 'off',
+
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
diff --git a/.github/actions/setup-javascript/action.yml b/.github/actions/setup-javascript/action.yml
index 07fd4d08d3..808adc7de6 100644
--- a/.github/actions/setup-javascript/action.yml
+++ b/.github/actions/setup-javascript/action.yml
@@ -23,7 +23,7 @@ runs:
shell: bash
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
- - uses: actions/cache@v3
+ - uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
diff --git a/.github/codecov.yml b/.github/codecov.yml
index 5532c49618..9d6413a106 100644
--- a/.github/codecov.yml
+++ b/.github/codecov.yml
@@ -1,3 +1,4 @@
+comment: false # Do not leave PR comments
coverage:
status:
project:
@@ -8,6 +9,3 @@ coverage:
default:
# Github status check is not blocking
informational: true
-comment:
- # Only write a comment in PR if there are changes
- require_changes: true
diff --git a/.github/renovate.json5 b/.github/renovate.json5
index dab99829a1..e92608a437 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -125,6 +125,22 @@
],
groupName: null, // We dont want them to belong to any group
},
+ {
+ // Group all RuboCop packages with `rubocop` in the same PR
+ matchManagers: ['bundler'],
+ matchPackageNames: ['rubocop'],
+ matchPackagePrefixes: ['rubocop-'],
+ matchUpdateTypes: ['patch', 'minor'],
+ groupName: 'RuboCop (non-major)',
+ },
+ {
+ // Group all RSpec packages with `rspec` in the same PR
+ matchManagers: ['bundler'],
+ matchPackageNames: ['rspec'],
+ matchPackagePrefixes: ['rspec-'],
+ matchUpdateTypes: ['patch', 'minor'],
+ groupName: 'RSpec (non-major)',
+ },
// Add labels depending on package manager
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },
diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml
index 99271b127b..d5023c53e7 100644
--- a/.github/workflows/crowdin-download.yml
+++ b/.github/workflows/crowdin-download.yml
@@ -53,7 +53,7 @@ jobs:
# Create or update the pull request
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v5.0.2
+ uses: peter-evans/create-pull-request@v6.0.2
with:
commit-message: 'New Crowdin translations'
title: 'New Crowdin Translations (automated)'
diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml
new file mode 100644
index 0000000000..2d483b5022
--- /dev/null
+++ b/.github/workflows/format-check.yml
@@ -0,0 +1,18 @@
+name: Check formatting
+on:
+ push:
+ pull_request:
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Clone repository
+ uses: actions/checkout@v4
+
+ - name: Set up Javascript environment
+ uses: ./.github/actions/setup-javascript
+
+ - name: Check formatting with Prettier
+ run: yarn format:check
diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml
index 7229bec582..e5f4874877 100644
--- a/.github/workflows/lint-css.yml
+++ b/.github/workflows/lint-css.yml
@@ -43,4 +43,4 @@ jobs:
- run: echo "::add-matcher::.github/stylelint-matcher.json"
- name: Stylelint
- run: yarn lint:sass
+ run: yarn lint:css
diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml
index 8dcab845ee..25615b720d 100644
--- a/.github/workflows/lint-haml.yml
+++ b/.github/workflows/lint-haml.yml
@@ -36,4 +36,4 @@ jobs:
- name: Run haml-lint
run: |
echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json"
- bundle exec haml-lint
+ bundle exec haml-lint --reporter github
diff --git a/.github/workflows/lint-json.yml b/.github/workflows/lint-json.yml
deleted file mode 100644
index 7796bf92c4..0000000000
--- a/.github/workflows/lint-json.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: JSON Linting
-on:
- push:
- branches-ignore:
- - 'dependabot/**'
- - 'renovate/**'
- paths:
- - 'package.json'
- - 'yarn.lock'
- - '.nvmrc'
- - '.prettier*'
- - '**/*.json'
- - '.github/workflows/lint-json.yml'
- - '!app/javascript/mastodon/locales/*.json'
-
- pull_request:
- paths:
- - 'package.json'
- - 'yarn.lock'
- - '.nvmrc'
- - '.prettier*'
- - '**/*.json'
- - '.github/workflows/lint-json.yml'
- - '!app/javascript/mastodon/locales/*.json'
-
-jobs:
- lint:
- runs-on: ubuntu-latest
-
- steps:
- - name: Clone repository
- uses: actions/checkout@v4
-
- - name: Set up Javascript environment
- uses: ./.github/actions/setup-javascript
-
- - name: Prettier
- run: yarn lint:json
diff --git a/.github/workflows/lint-md.yml b/.github/workflows/lint-md.yml
deleted file mode 100644
index 51c59937a3..0000000000
--- a/.github/workflows/lint-md.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Markdown Linting
-on:
- push:
- branches-ignore:
- - 'dependabot/**'
- - 'renovate/**'
- paths:
- - '.github/workflows/lint-md.yml'
- - '.nvmrc'
- - '.prettier*'
- - '**/*.md'
- - '!AUTHORS.md'
- - 'package.json'
- - 'yarn.lock'
-
- pull_request:
- paths:
- - '.github/workflows/lint-md.yml'
- - '.nvmrc'
- - '.prettier*'
- - '**/*.md'
- - '!AUTHORS.md'
- - 'package.json'
- - 'yarn.lock'
-
-jobs:
- lint:
- runs-on: ubuntu-latest
-
- steps:
- - name: Clone repository
- uses: actions/checkout@v4
-
- - name: Set up Javascript environment
- uses: ./.github/actions/setup-javascript
-
- - name: Prettier
- run: yarn lint:md
diff --git a/.github/workflows/lint-yml.yml b/.github/workflows/lint-yml.yml
deleted file mode 100644
index 908bdef5cc..0000000000
--- a/.github/workflows/lint-yml.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-name: YML Linting
-on:
- push:
- branches-ignore:
- - 'dependabot/**'
- - 'renovate/**'
- paths:
- - 'package.json'
- - 'yarn.lock'
- - '.nvmrc'
- - '.prettier*'
- - '**/*.yaml'
- - '**/*.yml'
- - '.github/workflows/lint-yml.yml'
- - '!config/locales/*.yml'
-
- pull_request:
- paths:
- - 'package.json'
- - 'yarn.lock'
- - '.nvmrc'
- - '.prettier*'
- - '**/*.yaml'
- - '**/*.yml'
- - '.github/workflows/lint-yml.yml'
- - '!config/locales/*.yml'
-
-jobs:
- lint:
- runs-on: ubuntu-latest
-
- steps:
- - name: Clone repository
- uses: actions/checkout@v4
-
- - name: Set up Javascript environment
- uses: ./.github/actions/setup-javascript
-
- - name: Prettier
- run: yarn lint:yml
diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml
index 346703ced4..624c3b7a2f 100644
--- a/.github/workflows/test-ruby.yml
+++ b/.github/workflows/test-ruby.yml
@@ -114,6 +114,7 @@ jobs:
- '3.0'
- '3.1'
- '.ruby-version'
+ - '3.3'
steps:
- uses: actions/checkout@v4
@@ -139,7 +140,7 @@ jobs:
- name: Upload coverage reports to Codecov
if: matrix.ruby-version == '.ruby-version'
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v4
with:
files: coverage/lcov/mastodon.lcov
@@ -189,6 +190,7 @@ jobs:
- '3.0'
- '3.1'
- '.ruby-version'
+ - '3.3'
steps:
- uses: actions/checkout@v4
@@ -224,7 +226,7 @@ jobs:
if: failure()
with:
name: e2e-screenshots
- path: tmp/screenshots/
+ path: tmp/capybara/
test-search:
name: Elastic Search integration testing
@@ -288,6 +290,7 @@ jobs:
- '3.0'
- '3.1'
- '.ruby-version'
+ - '3.3'
search-image:
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
include:
@@ -328,4 +331,4 @@ jobs:
if: failure()
with:
name: test-search-screenshots
- path: tmp/screenshots/
+ path: tmp/capybara/
diff --git a/.haml-lint.yml b/.haml-lint.yml
index 8cfcaec8d9..2b553ca56c 100644
--- a/.haml-lint.yml
+++ b/.haml-lint.yml
@@ -1,5 +1,3 @@
-inherits_from: .haml-lint_todo.yml
-
exclude:
- 'vendor/**/*'
- lib/templates/haml/scaffold/_form.html.haml
@@ -14,3 +12,5 @@ linters:
enabled: true
LineLength:
max: 320
+ ViewLength:
+ max: 200 # Override default value of 100 inherited from rubocop
diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml
deleted file mode 100644
index af2d2e8f4e..0000000000
--- a/.haml-lint_todo.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# This configuration was generated by
-# `haml-lint --auto-gen-config`
-# on 2024-01-09 11:30:07 -0500 using Haml-Lint version 0.53.0.
-# The point is for the user to remove these configuration records
-# one by one as the lints are removed from the code base.
-# Note that changes in the inspected code, or installation of new
-# versions of Haml-Lint, may require this file to be generated again.
-
-linters:
- # Offense count: 1
- LineLength:
- exclude:
- - 'app/views/admin/roles/_form.html.haml'
diff --git a/.husky/pre-commit b/.husky/pre-commit
index d2ae35e84b..3723623171 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,4 +1 @@
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
yarn lint-staged
diff --git a/.prettierignore b/.prettierignore
index 66ca9ee5b0..ad88ad3f97 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -54,6 +54,13 @@
# Ignore Docker option files
docker-compose.override.yml
+# Ignore public
+/public/assets
+/public/emoji
+/public/packs
+/public/packs-test
+/public/system
+
# Ignore emoji map file
/app/javascript/mastodon/features/emoji/emoji_map.json
@@ -74,6 +81,7 @@ app/javascript/styles/mastodon/reset.scss
# Ignore the generated AUTHORS.md
AUTHORS.md
+# Process a few selected JS files
!lint-staged.config.js
# Ignore glitch-soc emoji map file
diff --git a/.rubocop.yml b/.rubocop.yml
index 64021b4cec..d968346f6b 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -96,13 +96,6 @@ Rails/FilePath:
Rails/HttpStatus:
EnforcedStyle: numeric
-# Reason: Allowed in `tootctl` CLI code and in boot ENV checker
-# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
-Rails/Exit:
- Exclude:
- - 'config/boot.rb'
- - 'lib/mastodon/cli/*.rb'
-
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
Rails/LexicallyScopedActionFilter:
@@ -135,6 +128,11 @@ Rails/UnusedIgnoredColumns:
Rails/NegateInclude:
Enabled: false
+# Reason: Enforce default limit, but allow some elements to span lines
+# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecexamplelength
+RSpec/ExampleLength:
+ CountAsOne: ['array', 'heredoc', 'method_call']
+
# Reason: Deprecated cop, will be removed in 3.0, replaced by SpecFilePathFormat
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
RSpec/FilePath:
@@ -175,6 +173,15 @@ Style/ClassAndModuleChildren:
Style/Documentation:
Enabled: false
+# Reason: Route redirects are not token-formatted and must be skipped
+# https://docs.rubocop.org/rubocop/cops_style.html#styleformatstringtoken
+Style/FormatStringToken:
+ inherit_mode:
+ merge:
+ - AllowedMethods # The rubocop-rails config adds `redirect`
+ AllowedMethods:
+ - redirect_with_vary
+
# Reason: Enforce modern Ruby style
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
Style/HashSyntax:
@@ -203,11 +210,6 @@ Style/RedundantBegin:
Style/RescueStandardError:
EnforcedStyle: implicit
-# Reason: Simplify some spec layouts
-# https://docs.rubocop.org/rubocop/cops_style.html#stylesemicolon
-Style/Semicolon:
- AllowAsExpressionSeparator: true
-
# Reason: Originally disabled for CodeClimate, and no config consensus has been found
# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray
Style/SymbolArray:
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 47c49cb9a4..e7d1d08011 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -36,10 +36,10 @@ Metrics/PerceivedComplexity:
# Configuration parameters: CountAsOne.
RSpec/ExampleLength:
- Max: 22
+ Max: 20 # Override default of 5
RSpec/MultipleExpectations:
- Max: 8
+ Max: 7
# Configuration parameters: AllowSubject.
RSpec/MultipleMemoizedHelpers:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a53790afaf..cfdd0955b0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,1036 +1,25 @@
# Changelog
-All notable changes to this project will be documented in this file.
+All changes to Catstodon that aren't Mastodon or glitch-soc Mastodon changes will be documented here.
-## [4.2.7] - 2024-02-16
+## [v4.3.0-alpha.3+glitch+cat+1.1.2] - 2024-04-11
-### Fixed
+- Glitch-soc changes, most notably notifications about severed connections.
+ - Wow, my Python code to do the same manually was finally rendered obsolete!
-- Fix OmniAuth tests and edge cases in error handling ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29201), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/29207))
-- Fix new installs by upgrading to the latest release of the `nsa` gem, instead of a no longer existing commit ([mjankowski](https://github.com/mastodon/mastodon/pull/29065))
+## [v4.3.0-alpha.3+glitch+cat+1.0.9] - 2024-03-03
-### Security
+- Glitch-soc changes again (this time, among other stuff, the search bar icon position is fixed)
-- Fix insufficient checking of remote posts ([GHSA-jhrq-qvrm-qr36](https://github.com/mastodon/mastodon/security/advisories/GHSA-jhrq-qvrm-qr36))
+## [v4.3.0-alpha.3+glitch+cat+1.0.8] - 2024-02-29
-## [4.2.6] - 2024-02-14
+- Update translations from glitch-soc
+- glitch-soc now uses openURL function from upstream
-### Security
+## [v4.3.0-alpha.3+glitch+cat+1.0.7] - 2024-02-28
-- Update the `sidekiq-unique-jobs` dependency (see [GHSA-cmh9-rx85-xj38](https://github.com/mhenrixon/sidekiq-unique-jobs/security/advisories/GHSA-cmh9-rx85-xj38))
- In addition, we have disabled the web interface for `sidekiq-unique-jobs` out of caution.
- If you need it, you can re-enable it by setting `ENABLE_SIDEKIQ_UNIQUE_JOBS_UI=true`.
- If you only need to clear all locks, you can now use `bundle exec rake sidekiq_unique_jobs:delete_all_locks`.
-- Update the `nokogiri` dependency (see [GHSA-xc9x-jj77-9p9j](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-xc9x-jj77-9p9j))
-- Disable administrative Doorkeeper routes ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/29187))
-- Fix ongoing streaming sessions not being invalidated when applications get deleted in some cases ([GHSA-7w3c-p9j8-mq3x](https://github.com/mastodon/mastodon/security/advisories/GHSA-7w3c-p9j8-mq3x))
- In some rare cases, the streaming server was not notified of access tokens revocation on application deletion.
-- Change external authentication behavior to never reattach a new identity to an existing user by default ([GHSA-vm39-j3vx-pch3](https://github.com/mastodon/mastodon/security/advisories/GHSA-vm39-j3vx-pch3))
- Up until now, Mastodon has allowed new identities from external authentication providers to attach to an existing local user based on their verified e-mail address.
- This allowed upgrading users from a database-stored password to an external authentication provider, or move from one authentication provider to another.
- However, this behavior may be unexpected, and means that when multiple authentication providers are configured, the overall security would be that of the least secure authentication provider.
- For these reasons, this behavior is now locked under the `ALLOW_UNSAFE_AUTH_PROVIDER_REATTACH` environment variable.
- In addition, regardless of this environment variable, Mastodon will refuse to attach two identities from the same authentication provider to the same account.
+- Merged glitch-soc changes (incl. comments on admin/instances page)
-## [4.2.5] - 2024-02-01
+## [v4.3.0-alpha.3+glitch+cat+1.0.6] - 2024-02-25
-### Security
-
-- Fix insufficient origin validation (CVE-2024-23832, [GHSA-3fjr-858r-92rw](https://github.com/mastodon/mastodon/security/advisories/GHSA-3fjr-858r-92rw))
-
-## [4.2.4] - 2024-01-24
-
-### Fixed
-
-- Fix error when processing remote files with unusually long names ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28823))
-- Fix processing of compacted single-item JSON-LD collections ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28816))
-- Retry 401 errors on replies fetching ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/28788))
-- Fix `RecordNotUnique` errors in LinkCrawlWorker ([tribela](https://github.com/mastodon/mastodon/pull/28748))
-- Fix Mastodon not correctly processing HTTP Signatures with query strings ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28443), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/28476))
-- Fix potential redirection loop of streaming endpoint ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28665))
-- Fix streaming API redirection ignoring the port of `streaming_api_base_url` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28558))
-- Fix error when processing link preview with an array as `inLanguage` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28252))
-- Fix unsupported time zone or locale preventing sign-up ([Gargron](https://github.com/mastodon/mastodon/pull/28035))
-- Fix "Hide these posts from home" list setting not refreshing when switching lists ([brianholley](https://github.com/mastodon/mastodon/pull/27763))
-- Fix missing background behind dismissable banner in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/27479))
-- Fix line wrapping of language selection button with long locale codes ([gunchleoc](https://github.com/mastodon/mastodon/pull/27100), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27127))
-- Fix `Undo Announce` activity not being sent to non-follower authors ([MitarashiDango](https://github.com/mastodon/mastodon/pull/18482))
-- Fix N+1s because of association preloaders not actually getting called ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28339))
-- Fix empty column explainer getting cropped under certain conditions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28337))
-- Fix `LinkCrawlWorker` error when encountering empty OEmbed response ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28268))
-- Fix call to inefficient `delete_matched` cache method in domain blocks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28367))
-
-### Security
-
-- Add rate-limit of TOTP authentication attempts at controller level ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28801))
-
-## [4.2.3] - 2023-12-05
-
-### Fixed
-
-- Fix dependency on `json-canonicalization` version that has been made unavailable since last release
-
-## [4.2.2] - 2023-12-04
-
-### Changed
-
-- Change dismissed banners to be stored server-side ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27055))
-- Change GIF max matrix size error to explicitly mention GIF files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27927))
-- Change `Follow` activities delivery to bypass availability check ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/27586))
-- Change single-column navigation notice to be displayed outside of the logo container ([renchap](https://github.com/mastodon/mastodon/pull/27462), [renchap](https://github.com/mastodon/mastodon/pull/27476))
-- Change Content-Security-Policy to be tighter on media paths ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26889))
-- Change post language code to include country code when relevant ([gunchleoc](https://github.com/mastodon/mastodon/pull/27099), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27207))
-
-### Fixed
-
-- Fix upper border radius of onboarding columns ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27890))
-- Fix incoming status creation date not being restricted to standard ISO8601 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27655), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/28081))
-- Fix some posts from threads received out-of-order sometimes not being inserted into timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27653))
-- Fix posts from force-sensitized accounts being able to trend ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27620))
-- Fix error when trying to delete already-deleted file with OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27569))
-- Fix batch attachment deletion when using OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27554))
-- Fix processing LDSigned activities from actors with unknown public keys ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27474))
-- Fix error and incorrect URLs in `/api/v1/accounts/:id/featured_tags` for remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27459))
-- Fix report processing notice not mentioning the report number when performing a custom action ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27442))
-- Fix handling of `inLanguage` attribute in preview card processing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27423))
-- Fix own posts being removed from home timeline when unfollowing a used hashtag ([kmycode](https://github.com/mastodon/mastodon/pull/27391))
-- Fix some link anchors being recognized as hashtags ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27271), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27584))
-- Fix format-dependent redirects being cached regardless of requested format ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27634))
-
-## [4.2.1] - 2023-10-10
-
-### Added
-
-- Add redirection on `/deck` URLs for logged-out users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27128))
-- Add support for v4.2.0 migrations to `tootctl maintenance fix-duplicates` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27147))
-
-### Changed
-
-- Change some worker lock TTLs to be shorter-lived ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27246))
-- Change user archive export allowed period from 7 days to 6 days ([suddjian](https://github.com/mastodon/mastodon/pull/27200))
-
-### Fixed
-
-- Fix duplicate reports being sent when reporting some remote posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27355))
-- Fix clicking on already-opened thread post scrolling to the top of the thread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27331), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27338), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27350))
-- Fix some remote posts getting truncated ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27307))
-- Fix some cases of infinite scroll code trying to fetch inaccessible posts in a loop ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27286))
-- Fix `Vary` headers not being set on some redirects ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27272))
-- Fix mentions being matched in some URL query strings ([mjankowski](https://github.com/mastodon/mastodon/pull/25656))
-- Fix unexpected linebreak in version string in the Web UI ([vmstan](https://github.com/mastodon/mastodon/pull/26986))
-- Fix double scroll bars in some columns in advanced interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27187))
-- Fix boosts of local users being filtered in account timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27204))
-- Fix multiple instances of the trend refresh scheduler sometimes running at once ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27253))
-- Fix importer returning negative row estimates ([jgillich](https://github.com/mastodon/mastodon/pull/27258))
-- Fix incorrectly keeping outdated update notices absent from the API endpoint ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27021))
-- Fix import progress not updating on certain failures ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27247))
-- Fix websocket connections being incorrectly decremented twice on errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/27238))
-- Fix explore prompt appearing because of posts being received out of order ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27211))
-- Fix explore prompt sometimes showing up when the home TL is loading ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27062))
-- Fix link handling of mentions in user profiles when logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27185))
-- Fix filtering audit log for entries about disabling 2FA ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27186))
-- Fix notification toasts not respecting reduce-motion ([c960657](https://github.com/mastodon/mastodon/pull/27178))
-- Fix retention dashboard not displaying correct month ([vmstan](https://github.com/mastodon/mastodon/pull/27180))
-- Fix tIME chunk not being properly removed from PNG uploads ([TheEssem](https://github.com/mastodon/mastodon/pull/27111))
-- Fix division by zero in video in bitrate computation code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27129))
-- Fix inefficient queries in “Follows and followers” as well as several admin pages ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27116), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27306))
-- Fix ActiveRecord using two connection pools when no replica is defined ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27061))
-- Fix the search documentation URL in system checks ([renchap](https://github.com/mastodon/mastodon/pull/27036))
-
-## [4.2.0] - 2023-09-21
-
-The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by [@danielmbrasil](https://github.com/danielmbrasil), [@mjankowski](https://github.com/mjankowski), [@nschonni](https://github.com/nschonni), [@renchap](https://github.com/renchap), and [@takayamaki](https://github.com/takayamaki).
-
-### Added
-
-- **Add full-text search of opted-in public posts and rework search operators** ([Gargron](https://github.com/mastodon/mastodon/pull/26485), [jsgoldstein](https://github.com/mastodon/mastodon/pull/26344), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26657), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26650), [jsgoldstein](https://github.com/mastodon/mastodon/pull/26659), [Gargron](https://github.com/mastodon/mastodon/pull/26660), [Gargron](https://github.com/mastodon/mastodon/pull/26663), [Gargron](https://github.com/mastodon/mastodon/pull/26688), [Gargron](https://github.com/mastodon/mastodon/pull/26689), [Gargron](https://github.com/mastodon/mastodon/pull/26686), [Gargron](https://github.com/mastodon/mastodon/pull/26687), [Gargron](https://github.com/mastodon/mastodon/pull/26692), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26697), [Gargron](https://github.com/mastodon/mastodon/pull/26699), [Gargron](https://github.com/mastodon/mastodon/pull/26701), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26710), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26739), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26754), [Gargron](https://github.com/mastodon/mastodon/pull/26662), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26755), [Gargron](https://github.com/mastodon/mastodon/pull/26781), [Gargron](https://github.com/mastodon/mastodon/pull/26782), [Gargron](https://github.com/mastodon/mastodon/pull/26760), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26756), [Gargron](https://github.com/mastodon/mastodon/pull/26784), [Gargron](https://github.com/mastodon/mastodon/pull/26807), [Gargron](https://github.com/mastodon/mastodon/pull/26835), [Gargron](https://github.com/mastodon/mastodon/pull/26847), [Gargron](https://github.com/mastodon/mastodon/pull/26834), [arbolitoloco1](https://github.com/mastodon/mastodon/pull/26893), [tribela](https://github.com/mastodon/mastodon/pull/26896), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26927), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26959), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27014))
- This introduces a new `public_statuses` Elasticsearch index for public posts by users who have opted in to their posts being searchable (`toot#indexable` flag).
- This also revisits the other indexes to provide more useful indexing, and adds new search operators such as `from:me`, `before:2022-11-01`, `after:2022-11-01`, `during:2022-11-01`, `language:fr`, `has:poll`, or `in:library` (for searching only in posts you have written or interacted with).
- Results are now ordered chronologically.
-- **Add admin notifications for new Mastodon versions** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26582))
- This is done by querying `https://api.joinmastodon.org/update-check` every 30 minutes in a background job.
- That URL can be changed using the `UPDATE_CHECK_URL` environment variable, and the feature outright disabled by setting that variable to an empty string (`UPDATE_CHECK_URL=`).
-- **Add “Privacy and reach” tab in profile settings** ([Gargron](https://github.com/mastodon/mastodon/pull/26484), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26508))
- This reorganized scattered privacy and reach settings to a single place, as well as improve their wording.
-- **Add display of out-of-band hashtags in the web interface** ([Gargron](https://github.com/mastodon/mastodon/pull/26492), [arbolitoloco1](https://github.com/mastodon/mastodon/pull/26497), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26506), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26525), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26606), [Gargron](https://github.com/mastodon/mastodon/pull/26666), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26960))
-- **Add role badges to the web interface** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25649), [Gargron](https://github.com/mastodon/mastodon/pull/26281))
-- **Add ability to pick domains to forward reports to using the `forward_to_domains` parameter in `POST /api/v1/reports`** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25866), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26636))
- The `forward_to_domains` REST API parameter is a list of strings. If it is empty or omitted, the previous behavior is maintained.
- The `forward` parameter still needs to be set for `forward_to_domains` to be taken into account.
- The forwarded-to domains can only include that of the original author and people being replied to.
-- **Add forwarding of reported replies to servers being replied to** ([Gargron](https://github.com/mastodon/mastodon/pull/25341), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26189))
-- Add `ONE_CLICK_SSO_LOGIN` environment variable to directly link to the Single-Sign On provider if there is only one sign up method available ([CSDUMMI](https://github.com/mastodon/mastodon/pull/26083), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26368), [CSDUMMI](https://github.com/mastodon/mastodon/pull/26857), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26901))
-- **Add webhook templating** ([Gargron](https://github.com/mastodon/mastodon/pull/23289))
-- **Add webhooks for local `status.created`, `status.updated`, `account.updated` and `report.updated`** ([VyrCossont](https://github.com/mastodon/mastodon/pull/24133), [VyrCossont](https://github.com/mastodon/mastodon/pull/24243), [VyrCossont](https://github.com/mastodon/mastodon/pull/24211))
-- **Add exclusive lists** ([dariusk, necropolina](https://github.com/mastodon/mastodon/pull/22048), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25324))
-- **Add a confirmation screen when suspending a domain** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25144), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25603))
-- **Add support for importing lists** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25203), [mgmn](https://github.com/mastodon/mastodon/pull/26120), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26372))
-- **Add optional hCaptcha support** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25019), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25057), [Gargron](https://github.com/mastodon/mastodon/pull/25395), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26388))
-- **Add lines to threads in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24549), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24677), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24696), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24711), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24714), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24713), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24715), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24800), [teeerevor](https://github.com/mastodon/mastodon/pull/25706), [renchap](https://github.com/mastodon/mastodon/pull/25807))
-- **Add new onboarding flow to web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24619), [Gargron](https://github.com/mastodon/mastodon/pull/24646), [Gargron](https://github.com/mastodon/mastodon/pull/24705), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24872), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/24883), [Gargron](https://github.com/mastodon/mastodon/pull/24954), [stevenjlm](https://github.com/mastodon/mastodon/pull/24959), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25010), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25275), [Gargron](https://github.com/mastodon/mastodon/pull/25559), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25561))
-- **Add auto-refresh of accounts we get new messages/edits of** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26510))
-- **Add Elasticsearch cluster health check and indexes mismatch check to dashboard** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26448), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26605), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26658))
-- Add `hide_collections`, `discoverable` and `indexable` attributes to credentials API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26998))
-- Add `S3_ENABLE_CHECKSUM_MODE` environment variable to enable checksum verification on compatible S3-providers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26435))
-- Add admin API for managing tags ([rrgeorge](https://github.com/mastodon/mastodon/pull/26872))
-- Add a link to hashtag timelines from the Trending hashtags moderation interface ([gunchleoc](https://github.com/mastodon/mastodon/pull/26724))
-- Add timezone to datetimes in e-mails ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26822))
-- Add `authorized_fetch` server setting in addition to env var ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26958))
-- Add avatar image to webfinger responses ([tvler](https://github.com/mastodon/mastodon/pull/26558))
-- Add debug logging on signature verification failure ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26637), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26812))
-- Add explicit error messages when DeepL quota is exceeded ([lutoma](https://github.com/mastodon/mastodon/pull/26704))
-- Add Elasticsearch/OpenSearch version to “Software” in admin dashboard ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26652))
-- Add `data-nosnippet` attribute to remote posts and local posts with `noindex` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26648))
-- Add support for federating `memorial` attribute ([rrgeorge](https://github.com/mastodon/mastodon/pull/26583))
-- Add Cherokee and Kalmyk to languages dropdown ([gunchleoc](https://github.com/mastodon/mastodon/pull/26012), [gunchleoc](https://github.com/mastodon/mastodon/pull/26013))
-- Add `DELETE /api/v1/profile/avatar` and `DELETE /api/v1/profile/header` to the REST API ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25124), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26573))
-- Add `ES_PRESET` option to customize numbers of shards and replicas ([Gargron](https://github.com/mastodon/mastodon/pull/26483), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26489))
- This can have a value of `single_node_cluster` (default), `small_cluster` (uses one replica) or `large_cluster` (uses one replica and a higher number of shards).
-- Add `CACHE_BUSTER_HTTP_METHOD` environment variable ([renchap](https://github.com/mastodon/mastodon/pull/26528), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26542))
-- Add support for `DB_PASS` when using `DATABASE_URL` ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26295))
-- Add `GET /api/v1/instance/languages` to REST API ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24443))
-- Add primary key to `preview_cards_statuses` join table ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25243), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26384), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26447), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26737), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26979))
-- Add client-side timeout on resend confirmation button ([Gargron](https://github.com/mastodon/mastodon/pull/26300))
-- Add published date and author to news on the explore screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26155))
-- Add `lang` attribute to various UI components ([c960657](https://github.com/mastodon/mastodon/pull/23869), [c960657](https://github.com/mastodon/mastodon/pull/23891), [c960657](https://github.com/mastodon/mastodon/pull/26111), [c960657](https://github.com/mastodon/mastodon/pull/26149))
-- Add stricter protocol fields validation for accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25937))
-- Add support for Azure blob storage ([mistydemeo](https://github.com/mastodon/mastodon/pull/23607), [mistydemeo](https://github.com/mastodon/mastodon/pull/26080))
-- Add toast with option to open post after publishing in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25564), [Signez](https://github.com/mastodon/mastodon/pull/25919), [Gargron](https://github.com/mastodon/mastodon/pull/26664))
-- Add canonical link tags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25715))
-- Add button to see results for polls in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25726))
-- Add at-symbol prepended to mention span title ([forsamori](https://github.com/mastodon/mastodon/pull/25684))
-- Add users index on `unconfirmed_email` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25672), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25702))
-- Add superapp index on `oauth_applications` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25670))
-- Add index to backups on `user_id` column ([mjankowski](https://github.com/mastodon/mastodon/pull/25647))
-- Add onboarding prompt when home feed too slow in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25267), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25556), [Gargron](https://github.com/mastodon/mastodon/pull/25579), [renchap](https://github.com/mastodon/mastodon/pull/25580), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25581), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25617), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25917), [Gargron](https://github.com/mastodon/mastodon/pull/26829), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26935))
-- Add `POST /api/v1/conversations/:id/unread` API endpoint to mark a conversation as unread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25509))
-- Add `translate="no"` to outgoing mentions and links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25524))
-- Add unsubscribe link and headers to e-mails ([Gargron](https://github.com/mastodon/mastodon/pull/25378), [c960657](https://github.com/mastodon/mastodon/pull/26085))
-- Add logging of websocket send errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25280))
-- Add time zone preference ([Gargron](https://github.com/mastodon/mastodon/pull/25342), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26025))
-- Add `legal` as report category ([Gargron](https://github.com/mastodon/mastodon/pull/23941), [renchap](https://github.com/mastodon/mastodon/pull/25400), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26509))
-- Add `data-nosnippet` so Google doesn't use trending posts in snippets for `/` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25279))
-- Add card with who invited you to join when displaying rules on sign-up ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23475))
-- Add missing primary keys to `accounts_tags` and `statuses_tags` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25210))
-- Add support for custom sign-up URLs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25014), [renchap](https://github.com/mastodon/mastodon/pull/25108), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25190), [mgmn](https://github.com/mastodon/mastodon/pull/25531))
- This is set using `SSO_ACCOUNT_SIGN_UP` and reflected in the REST API by adding `registrations.sign_up_url` to the `/api/v2/instance` endpoint.
-- Add polling and automatic redirection to `/start` on email confirmation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25013))
-- Add ability to block sign-ups from IP using the CLI ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24870))
-- Add ALT badges to media that has alternative text in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24782), [c960657](https://github.com/mastodon/mastodon/pull/26166)
-- Add ability to include accounts with pending follow requests in lists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19727), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24810))
-- Add trend management to admin API ([rrgeorge](https://github.com/mastodon/mastodon/pull/24257))
- - `POST /api/v1/admin/trends/statuses/:id/approve`
- - `POST /api/v1/admin/trends/statuses/:id/reject`
- - `POST /api/v1/admin/trends/links/:id/approve`
- - `POST /api/v1/admin/trends/links/:id/reject`
- - `POST /api/v1/admin/trends/tags/:id/approve`
- - `POST /api/v1/admin/trends/tags/:id/reject`
- - `GET /api/v1/admin/trends/links/publishers`
- - `POST /api/v1/admin/trends/links/publishers/:id/approve`
- - `POST /api/v1/admin/trends/links/publishers/:id/reject`
-- Add user handle to notification mail recipient address ([HeitorMC](https://github.com/mastodon/mastodon/pull/24240))
-- Add progress indicator to sign-up flow ([Gargron](https://github.com/mastodon/mastodon/pull/24545))
-- Add client-side validation for taken username in sign-up form ([Gargron](https://github.com/mastodon/mastodon/pull/24546))
-- Add `--approve` option to `tootctl accounts create` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24533))
-- Add “In Memoriam” banner back to profiles ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23591), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23614))
- This adds the `memorial` attribute to the `Account` REST API entity.
-- Add colour to follow button when hashtag is being followed ([c960657](https://github.com/mastodon/mastodon/pull/24361))
-- Add further explanations to the profile link verification instructions ([drzax](https://github.com/mastodon/mastodon/pull/19723))
-- Add a link to Identity provider's account settings from the account settings ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24100), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24628))
-- Add support for streaming server to connect to postgres with self-signed certs through the `sslmode` URL parameter ([ramuuns](https://github.com/mastodon/mastodon/pull/21431))
-- Add support for specifying S3 storage classes through the `S3_STORAGE_CLASS` environment variable ([hyl](https://github.com/mastodon/mastodon/pull/22480))
-- Add support for incoming rich text ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23913))
-- Add support for Ruby 3.2 ([tenderlove](https://github.com/mastodon/mastodon/pull/22928), [casperisfine](https://github.com/mastodon/mastodon/pull/24142), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24202), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26934))
-- Add API parameter to safeguard unexpected mentions in new posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18350))
-
-### Changed
-
-- **Change hashtags to be displayed separately when they are the last line of a post** ([renchap](https://github.com/mastodon/mastodon/pull/26499), [renchap](https://github.com/mastodon/mastodon/pull/26614), [renchap](https://github.com/mastodon/mastodon/pull/26615))
-- **Change reblogs to be excluded from "Posts and replies" tab in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/26302))
-- **Change interaction modal in web interface** ([Gargron, ClearlyClaire](https://github.com/mastodon/mastodon/pull/26075), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26269), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26268), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26267), [mgmn](https://github.com/mastodon/mastodon/pull/26459), [tribela](https://github.com/mastodon/mastodon/pull/26461), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26593), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26795))
-- **Change design of link previews in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/26136), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26151), [Gargron](https://github.com/mastodon/mastodon/pull/26153), [Gargron](https://github.com/mastodon/mastodon/pull/26250), [Gargron](https://github.com/mastodon/mastodon/pull/26287), [Gargron](https://github.com/mastodon/mastodon/pull/26286), [c960657](https://github.com/mastodon/mastodon/pull/26184))
-- **Change "direct message" nomenclature to "private mention" in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24248))
-- **Change translation feature to cover Content Warnings, poll options and media descriptions** ([c960657](https://github.com/mastodon/mastodon/pull/24175), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/25251), [c960657](https://github.com/mastodon/mastodon/pull/26168), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26452))
-- **Change account search to match by text when opted-in** ([jsgoldstein](https://github.com/mastodon/mastodon/pull/25599), [Gargron](https://github.com/mastodon/mastodon/pull/26378))
-- **Change import feature to be clearer, less error-prone and more reliable** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21054), [mgmn](https://github.com/mastodon/mastodon/pull/24874))
-- **Change local and federated timelines to be tabs of a single “Live feeds” column** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25641), [Gargron](https://github.com/mastodon/mastodon/pull/25683), [mgmn](https://github.com/mastodon/mastodon/pull/25694), [Plastikmensch](https://github.com/mastodon/mastodon/pull/26247), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26633))
-- **Change user archive export to be faster and more reliable, and export `.zip` archives instead of `.tar.gz` ones** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23360), [TheEssem](https://github.com/mastodon/mastodon/pull/25034))
-- **Change `mastodon-streaming` systemd unit files to be templated** ([e-nomem](https://github.com/mastodon/mastodon/pull/24751))
-- **Change `statsd` integration to disable sidekiq metrics by default** ([mjankowski](https://github.com/mastodon/mastodon/pull/25265), [mjankowski](https://github.com/mastodon/mastodon/pull/25336), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26310))
- This deprecates `statsd` support and disables the sidekiq integration unless `STATSD_SIDEKIQ` is set to `true`.
- This is because the `nsa` gem is unmaintained, and its sidekiq integration is known to add very significant overhead.
- Later versions of Mastodon will have other ways to get the same metrics.
-- **Change replica support to native Rails adapter** ([krainboltgreene](https://github.com/mastodon/mastodon/pull/25693), [Gargron](https://github.com/mastodon/mastodon/pull/25849), [Gargron](https://github.com/mastodon/mastodon/pull/25874), [Gargron](https://github.com/mastodon/mastodon/pull/25851), [Gargron](https://github.com/mastodon/mastodon/pull/25977), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26074), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26326), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26386), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26856))
- This is a breaking change, dropping `makara` support, and requiring you to update your database configuration if you are using replicas.
- To tell Mastodon to use a read replica, you can either set the `REPLICA_DB_NAME` environment variable (along with `REPLICA_DB_USER`, `REPLICA_DB_PASS`, `REPLICA_DB_HOST`, and `REPLICA_DB_PORT`, if they differ from the primary database), or the `REPLICA_DATABASE_URL` environment variable if your configuration is based on `DATABASE_URL`.
-- Change DCT method used for JPEG encoding to float ([electroCutie](https://github.com/mastodon/mastodon/pull/26675))
-- Change from `node-redis` to `ioredis` for streaming ([gmemstr](https://github.com/mastodon/mastodon/pull/26581))
-- Change private statuses index to index without crutches ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26713))
-- Change video compression parameters ([Gargron](https://github.com/mastodon/mastodon/pull/26631), [Gargron](https://github.com/mastodon/mastodon/pull/26745), [Gargron](https://github.com/mastodon/mastodon/pull/26766), [Gargron](https://github.com/mastodon/mastodon/pull/26970))
-- Change admin e-mail notification settings to be their own settings group ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26596))
-- Change opacity of the delete icon in the search field to be more visible ([AntoninDelFabbro](https://github.com/mastodon/mastodon/pull/26449))
-- Change Account Search to prioritize username over display name ([jsgoldstein](https://github.com/mastodon/mastodon/pull/26623))
-- Change follow recommendation materialized view to be faster in most cases ([renchap, ClearlyClaire](https://github.com/mastodon/mastodon/pull/26545))
-- Change `robots.txt` to block GPTBot ([Foritus](https://github.com/mastodon/mastodon/pull/26396))
-- Change header of hashtag timelines in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26362), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26416))
-- Change streaming `/metrics` to include additional metrics ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26299), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26945))
-- Change indexing frequency from 5 minutes to 1 minute, add locks to schedulers ([Gargron](https://github.com/mastodon/mastodon/pull/26304))
-- Change column link to add a better keyboard focus indicator ([teeerevor](https://github.com/mastodon/mastodon/pull/26278))
-- Change poll form element colors to fit with the rest of the ui ([teeerevor](https://github.com/mastodon/mastodon/pull/26139), [teeerevor](https://github.com/mastodon/mastodon/pull/26162), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26164))
-- Change 'favourite' to 'favorite' for American English ([marekr](https://github.com/mastodon/mastodon/pull/24667), [gunchleoc](https://github.com/mastodon/mastodon/pull/26009), [nabijaczleweli](https://github.com/mastodon/mastodon/pull/26109))
-- Change ActivityStreams representation of suspended accounts to not use a blank `name` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25276))
-- Change focus UI for keyboard only input ([teeerevor](https://github.com/mastodon/mastodon/pull/25935), [Gargron](https://github.com/mastodon/mastodon/pull/26125), [Gargron](https://github.com/mastodon/mastodon/pull/26767))
-- Change thread view to scroll to the selected post rather than the post being replied to ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24685))
-- Change links in multi-column mode so tabs are open in single-column mode ([Signez](https://github.com/mastodon/mastodon/pull/25893), [Signez](https://github.com/mastodon/mastodon/pull/26070), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25973), [Signez](https://github.com/mastodon/mastodon/pull/26019), [Signez](https://github.com/mastodon/mastodon/pull/26759))
-- Change searching with `#` to include account index ([jsgoldstein](https://github.com/mastodon/mastodon/pull/25638))
-- Change label and design of sensitive and unavailable media in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25712), [Gargron](https://github.com/mastodon/mastodon/pull/26135), [Gargron](https://github.com/mastodon/mastodon/pull/26330))
-- Change button colors to increase hover/focus contrast and consistency ([teeerevor](https://github.com/mastodon/mastodon/pull/25677), [Gargron](https://github.com/mastodon/mastodon/pull/25679))
-- Change dropdown icon above compose form from ellipsis to bars in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25661))
-- Change header backgrounds to use fewer different colors in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25577))
-- Change files to be deleted in batches instead of one-by-one ([Gargron](https://github.com/mastodon/mastodon/pull/23302), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/25586), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25587))
-- Change emoji picker icon ([iparr](https://github.com/mastodon/mastodon/pull/25479))
-- Change edit profile page ([Gargron](https://github.com/mastodon/mastodon/pull/25413), [c960657](https://github.com/mastodon/mastodon/pull/26538))
-- Change "bot" label to "automated" ([Gargron](https://github.com/mastodon/mastodon/pull/25356))
-- Change design of dropdowns in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25107))
-- Change wording of “Content cache retention period” setting to highlight destructive implications ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23261))
-- Change autolinking to allow carets in URL search params ([renchap](https://github.com/mastodon/mastodon/pull/25216))
-- Change share action from being in action bar to being in dropdown in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25105))
-- Change sessions to be ordered from most-recent to least-recently updated ([frankieroberto](https://github.com/mastodon/mastodon/pull/25005))
-- Change vacuum scheduler to also delete expired tokens and unused application records ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24868), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24871))
-- Change "Sign in" to "Login" ([Gargron](https://github.com/mastodon/mastodon/pull/24942))
-- Change domain suspensions to also be checked before trying to fetch unknown remote resources ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24535))
-- Change media components to use aspect-ratio rather than compute height themselves ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24686), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24943), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26801))
-- Change logo version in header based on screen size in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24707))
-- Change label from "For you" to "People" on explore screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24706))
-- Change logged-out WebUI HTML pages to be cached for a few seconds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24708))
-- Change unauthenticated responses to be cached in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/24348), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24662), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24665))
-- Change HTTP caching logic ([Gargron](https://github.com/mastodon/mastodon/pull/24347), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24604))
-- Change hashtags and mentions in bios to open in-app in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24643))
-- Change styling of the recommended accounts to allow bio to be more visible ([chike00](https://github.com/mastodon/mastodon/pull/24480))
-- Change account search in moderation interface to allow searching by username including the leading `@` ([HeitorMC](https://github.com/mastodon/mastodon/pull/24242))
-- Change all components to use the same error page in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24512))
-- Change search pop-out in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24305))
-- Change user settings to be stored in a more optimal way ([Gargron](https://github.com/mastodon/mastodon/pull/23630), [c960657](https://github.com/mastodon/mastodon/pull/24321), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24453), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24460), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24558), [Gargron](https://github.com/mastodon/mastodon/pull/24761), [Gargron](https://github.com/mastodon/mastodon/pull/24783), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25508), [jsgoldstein](https://github.com/mastodon/mastodon/pull/25340), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26884), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27012))
-- Change media upload limits and remove client-side resizing ([Gargron](https://github.com/mastodon/mastodon/pull/23726))
-- Change design of account rows in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24247), [Gargron](https://github.com/mastodon/mastodon/pull/24343), [Gargron](https://github.com/mastodon/mastodon/pull/24956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25131))
-- Change log-out to use Single Logout when using external log-in through OIDC ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24020))
-- Change sidekiq-bulk's batch size from 10,000 to 1,000 jobs in one Redis call ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24034))
-- Change translation to only be offered for supported languages ([c960657](https://github.com/mastodon/mastodon/pull/23879), [c960657](https://github.com/mastodon/mastodon/pull/24037))
- This adds the `/api/v1/instance/translation_languages` REST API endpoint that returns an object with the supported translation language pairs in the form:
- ```json
- {
- "fr": ["en", "de"]
- }
- ```
- (where `fr` is a supported source language and `en` and `de` or supported output language when translating a `fr` string)
-- Change compose form checkbox to native input with `appearance: none` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22949))
-- Change posts' clickable area to be larger ([c960657](https://github.com/mastodon/mastodon/pull/23621))
-- Change `followed_by` link to `location=all` if account is local on /admin/accounts/:id page ([tribela](https://github.com/mastodon/mastodon/pull/23467))
-
-### Removed
-
-- **Remove support for Node.js 14** ([renchap](https://github.com/mastodon/mastodon/pull/25198))
-- **Remove support for Ruby 2.7** ([nschonni](https://github.com/mastodon/mastodon/pull/24237))
-- **Remove clustering from streaming API** ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/24655))
-- **Remove anonymous access to the streaming API** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23989))
-- Remove obfuscation of reply count in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26768))
-- Remove `kmr` from language selection, as it was a duplicate for `ku` ([gunchleoc](https://github.com/mastodon/mastodon/pull/26014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26787))
-- Remove 16:9 cropping from web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26132))
-- Remove back button from bookmarks, favourites and lists screens in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26126))
-- Remove display name input from sign-up form ([Gargron](https://github.com/mastodon/mastodon/pull/24704))
-- Remove `tai` locale ([c960657](https://github.com/mastodon/mastodon/pull/23880))
-- Remove empty Kushubian (csb) local files ([nschonni](https://github.com/mastodon/mastodon/pull/24151))
-- Remove `Permissions-Policy` header from all responses ([Gargron](https://github.com/mastodon/mastodon/pull/24124))
-
-### Fixed
-
-- **Fix filters not being applying in the explore page** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25887))
-- **Fix being unable to load past a full page of filtered posts in Home timeline** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24930))
-- **Fix log-in flow when involving both OAuth and external authentication** ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24073))
-- **Fix broken links in account gallery** ([c960657](https://github.com/mastodon/mastodon/pull/24218))
-- **Fix migration handler not updating lists** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24808))
-- Fix crash when viewing a moderation appeal and the moderator account has been deleted ([xrobau](https://github.com/mastodon/mastodon/pull/25900))
-- Fix error in Web UI when server rules cannot be fetched ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26957))
-- Fix paragraph margins resulting in irregular read-more cut-off in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26828))
-- Fix notification permissions being requested immediately after login ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26472))
-- Fix performances of profile directory ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26840), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26842))
-- Fix mute button and volume slider feeling disconnected in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26827), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26860))
-- Fix “Scoped order is ignored, it's forced to be batch order.” warnings ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26793))
-- Fix blocked domain appearing in account feeds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26823))
-- Fix invalid `Content-Type` header for WebP images ([c960657](https://github.com/mastodon/mastodon/pull/26773))
-- Fix minor inefficiencies in `tootctl search deploy` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26721))
-- Fix filter form in profiles directory overflowing instead of wrapping ([arbolitoloco1](https://github.com/mastodon/mastodon/pull/26682))
-- Fix sign up steps progress layout in right-to-left locales ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26728))
-- Fix bug with “favorited by” and “reblogged by“ view on posts only showing up to 40 items ([timothyjrogers](https://github.com/mastodon/mastodon/pull/26577), [timothyjrogers](https://github.com/mastodon/mastodon/pull/26574))
-- Fix bad search type heuristic ([Gargron](https://github.com/mastodon/mastodon/pull/26673))
-- Fix not being able to negate prefix clauses in search ([Gargron](https://github.com/mastodon/mastodon/pull/26672))
-- Fix timeout on invalid set of exclusionary parameters in `/api/v1/timelines/public` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/26239))
-- Fix adding column with default value taking longer on Postgres >= 11 ([Gargron](https://github.com/mastodon/mastodon/pull/26375))
-- Fix light theme select option for hashtags ([teeerevor](https://github.com/mastodon/mastodon/pull/26311))
-- Fix AVIF attachments ([c960657](https://github.com/mastodon/mastodon/pull/26264))
-- Fix incorrect URL normalization when fetching remote resources ([c960657](https://github.com/mastodon/mastodon/pull/26219), [c960657](https://github.com/mastodon/mastodon/pull/26285))
-- Fix being unable to filter posts for individual Chinese languages ([gunchleoc](https://github.com/mastodon/mastodon/pull/26066))
-- Fix preview card sometimes linking to 4xx error pages ([c960657](https://github.com/mastodon/mastodon/pull/26200))
-- Fix emoji picker button scrolling with textarea content in single-column view ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25304))
-- Fix missing border on error screen in light theme in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26152))
-- Fix UI overlap with the loupe icon in the Explore Tab ([gol-cha](https://github.com/mastodon/mastodon/pull/26113))
-- Fix unexpected redirection to `/explore` after sign-in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26143))
-- Fix `/api/v1/statuses/:id/unfavourite` and `/api/v1/statuses/:id/unreblog` returning non-updated counts ([c960657](https://github.com/mastodon/mastodon/pull/24365))
-- Fix clicking the “Back” button sometimes leading out of Mastodon ([c960657](https://github.com/mastodon/mastodon/pull/23953), [CSFlorin](https://github.com/mastodon/mastodon/pull/24835), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/24867), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25281))
-- Fix processing of `null` ActivityPub activities ([tribela](https://github.com/mastodon/mastodon/pull/26021))
-- Fix hashtag posts not being removed from home feed on hashtag unfollow ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26028))
-- Fix for "follows you" indicator in light web UI not readable ([vmstan](https://github.com/mastodon/mastodon/pull/25993))
-- Fix incorrect line break between icon and number of reposts & favourites ([edent](https://github.com/mastodon/mastodon/pull/26004))
-- Fix sounds not being loaded from assets host ([Signez](https://github.com/mastodon/mastodon/pull/25931))
-- Fix buttons showing inconsistent styles ([teeerevor](https://github.com/mastodon/mastodon/pull/25903), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25965), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26341), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26482))
-- Fix trend calculation working on too many items at a time ([Gargron](https://github.com/mastodon/mastodon/pull/25835))
-- Fix dropdowns being disabled for logged out users in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25714), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25964))
-- Fix explore page being inaccessible when opted-out of trends in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25716))
-- Fix re-activated accounts possibly getting deleted by `AccountDeletionWorker` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25711))
-- Fix `/api/v2/search` not working with following query param ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25681))
-- Fix inefficient query when requesting a new confirmation email from a logged-in account ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25669))
-- Fix unnecessary concurrent calls to `/api/*/instance` in web UI ([mgmn](https://github.com/mastodon/mastodon/pull/25663))
-- Fix resolving local URL for remote content ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25637))
-- Fix search not being easily findable on smaller screens in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25576), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25631))
-- Fix j/k keyboard shortcuts on some status lists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25554))
-- Fix missing validation on `default_privacy` setting ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25513))
-- Fix incorrect pagination headers in `/api/v2/admin/accounts` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25477))
-- Fix non-interactive upload container being given a `button` role and tabIndex ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25462))
-- Fix always redirecting to onboarding in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25396))
-- Fix inconsistent use of middle dot (·) instead of bullet (•) to separate items ([j-f1](https://github.com/mastodon/mastodon/pull/25248))
-- Fix spacing of middle dots in the detailed status meta section ([j-f1](https://github.com/mastodon/mastodon/pull/25247))
-- Fix prev/next buttons color in media viewer ([renchap](https://github.com/mastodon/mastodon/pull/25231))
-- Fix email addresses not being properly updated in `tootctl maintenance fix-duplicates` ([mjankowski](https://github.com/mastodon/mastodon/pull/25118))
-- Fix unicode surrogate pairs sometimes being broken in page title ([eai04191](https://github.com/mastodon/mastodon/pull/25148))
-- Fix various inefficient queries against account domains ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25126))
-- Fix video player offering to expand in a lightbox when it's in an `iframe` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25067))
-- Fix post embed previews ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25071))
-- Fix inadequate error handling in several API controllers when given invalid parameters ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24947), [danielmbrasil](https://github.com/mastodon/mastodon/pull/24958), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25063), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25072), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25386), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25595))
-- Fix uncaught `ActiveRecord::StatementInvalid` in Mastodon::IpBlocksCLI ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24861))
-- Fix various edge cases with local moves ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24812))
-- Fix `tootctl accounts cull` crashing when encountering a domain resolving to a private address ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23378))
-- Fix `tootctl accounts approve --number N` not aproving the N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605))
-- Fix being unable to clear media description when editing posts ([c960657](https://github.com/mastodon/mastodon/pull/24720))
-- Fix unavailable translations not falling back to English ([mgmn](https://github.com/mastodon/mastodon/pull/24727))
-- Fix anonymous visitors getting a session cookie on first visit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24584), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24650), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24664))
-- Fix cutting off first letter of hashtag links sometimes in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24623))
-- Fix crash in `tootctl accounts create --reattach --force` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24557), [danielmbrasil](https://github.com/mastodon/mastodon/pull/24680))
-- Fix characters being emojified even when using Variation Selector 15 (text) ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20949), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24615))
-- Fix uncaught ActiveRecord::StatementInvalid exception in `Mastodon::AccountsCLI#approve` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24590))
-- Fix email confirmation skip option in `tootctl accounts modify USERNAME --email EMAIL --confirm` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24578))
-- Fix tooltip for dates without time ([c960657](https://github.com/mastodon/mastodon/pull/24244))
-- Fix missing loading spinner and loading more on scroll in Private Mentions column ([c960657](https://github.com/mastodon/mastodon/pull/24446))
-- Fix account header image missing from `/settings/profile` on narrow screens ([c960657](https://github.com/mastodon/mastodon/pull/24433))
-- Fix height of announcements not being updated when using reduced animations ([c960657](https://github.com/mastodon/mastodon/pull/24354))
-- Fix inconsistent radius in advanced interface drawer ([thislight](https://github.com/mastodon/mastodon/pull/24407))
-- Fix loading more trending posts on scroll in the advanced interface ([OmmyZhang](https://github.com/mastodon/mastodon/pull/24314))
-- Fix poll ending notification for edited polls ([c960657](https://github.com/mastodon/mastodon/pull/24311))
-- Fix max width of media in `/about` and `/privacy-policy` ([mgmn](https://github.com/mastodon/mastodon/pull/24180))
-- Fix streaming API not being usable without `DATABASE_URL` ([Gargron](https://github.com/mastodon/mastodon/pull/23960))
-- Fix external authentication not running onboarding code for new users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23458))
-
-## [4.1.8] - 2023-09-19
-
-### Fixed
-
-- Fix post edits not being forwarded as expected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26936))
-- Fix moderator rights inconsistencies ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26729))
-- Fix crash when encountering invalid URL ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26814))
-- Fix cached posts including stale stats ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26409))
-- Fix uploading of video files for which `ffprobe` reports `0/0` average framerate ([NicolaiSoeborg](https://github.com/mastodon/mastodon/pull/26500))
-- Fix unexpected audio stream transcoding when uploaded video is eligible to passthrough ([yufushiro](https://github.com/mastodon/mastodon/pull/26608))
-
-### Security
-
-- Fix missing HTML sanitization in translation API (CVE-2023-42452, [GHSA-2693-xr3m-jhqr](https://github.com/mastodon/mastodon/security/advisories/GHSA-2693-xr3m-jhqr))
-- Fix incorrect domain name normalization (CVE-2023-42451, [GHSA-v3xf-c9qf-j667](https://github.com/mastodon/mastodon/security/advisories/GHSA-v3xf-c9qf-j667))
-
-## [4.1.7] - 2023-09-05
-
-### Changed
-
-- Change remote report processing to accept reports with long comments, but truncate them ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25028))
-
-### Fixed
-
-- **Fix blocking subdomains of an already-blocked domain** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26392))
-- Fix `/api/v1/timelines/tag/:hashtag` allowing for unauthenticated access when public preview is disabled ([danielmbrasil](https://github.com/mastodon/mastodon/pull/26237))
-- Fix inefficiencies in `PlainTextFormatter` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26727))
-
-## [4.1.6] - 2023-07-31
-
-### Fixed
-
-- Fix memory leak in streaming server ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26228))
-- Fix wrong filters sometimes applying in streaming ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26159), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26213), [renchap](https://github.com/mastodon/mastodon/pull/26233))
-- Fix incorrect connect timeout in outgoing requests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26116))
-
-## [4.1.5] - 2023-07-21
-
-### Added
-
-- Add check preventing Sidekiq workers from running with Makara configured ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25850))
-
-### Changed
-
-- Change request timeout handling to use a longer deadline ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26055))
-
-### Fixed
-
-- Fix moderation interface for remote instances with a .zip TLD ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25885))
-- Fix remote accounts being possibly persisted to database with incomplete protocol values ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25886))
-- Fix trending publishers table not rendering correctly on narrow screens ([vmstan](https://github.com/mastodon/mastodon/pull/25945))
-
-### Security
-
-- Fix CSP headers being unintentionally wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26105))
-
-## [4.1.4] - 2023-07-07
-
-### Fixed
-
-- Fix branding:generate_app_icons failing because of disallowed ICO coder ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25794))
-- Fix crash in admin interface when viewing a remote user with verified links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25796))
-- Fix processing of media files with unusual names ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25788))
-
-## [4.1.3] - 2023-07-06
-
-### Added
-
-- Add fallback redirection when getting a webfinger query `LOCAL_DOMAIN@LOCAL_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23600))
-
-### Changed
-
-- Change OpenGraph-based embeds to allow fullscreen ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25058))
-- Change AccessTokensVacuum to also delete expired tokens ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24868))
-- Change profile updates to be sent to recently-mentioned servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24852))
-- Change automatic post deletion thresholds and load detection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24614))
-- Change `/api/v1/statuses/:id/history` to always return at least one item ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25510))
-- Change auto-linking to allow carets in URL query params ([renchap](https://github.com/mastodon/mastodon/pull/25216))
-
-### Removed
-
-- Remove invalid `X-Frame-Options: ALLOWALL` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25070))
-
-### Fixed
-
-- Fix wrong view being displayed when a webhook fails validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25464))
-- Fix soft-deleted post cleanup scheduler overwhelming the streaming server ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25519))
-- Fix incorrect pagination headers in `/api/v2/admin/accounts` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25477))
-- Fix multiple inefficiencies in automatic post cleanup worker ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24607), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24785), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24840))
-- Fix performance of streaming by parsing message JSON once ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25278), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25361))
-- Fix CSP headers when `S3_ALIAS_HOST` includes a path component ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25273))
-- Fix `tootctl accounts approve --number N` not approving N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605))
-- Fix reports not being closed when performing batch suspensions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24988))
-- Fix being able to vote on your own polls ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25015))
-- Fix race condition when reblogging a status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25016))
-- Fix “Authorized applications” inefficiently and incorrectly getting last use date ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25060))
-- Fix “Authorized applications” crashing when listing apps with certain admin API scopes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25713))
-- Fix multiple N+1s in ConversationsController ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25134), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25399), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25499))
-- Fix user archive takeouts when using OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24431))
-- Fix searching for remote content by URL not working under certain conditions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25637))
-- Fix inefficiencies in indexing content for search ([VyrCossont](https://github.com/mastodon/mastodon/pull/24285), [VyrCossont](https://github.com/mastodon/mastodon/pull/24342))
-
-### Security
-
-- Add finer permission requirements for managing webhooks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25463))
-- Update dependencies
-- Add hardening headers for user-uploaded files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25756))
-- Fix verified links possibly hiding important parts of the URL (CVE-2023-36462)
-- Fix timeout handling of outbound HTTP requests (CVE-2023-36461)
-- Fix arbitrary file creation through media processing (CVE-2023-36460)
-- Fix possible XSS in preview cards (CVE-2023-36459)
-
-## [4.1.2] - 2023-04-04
-
-### Fixed
-
-- Fix crash in `tootctl` commands making use of parallelization when Elasticsearch is enabled ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24182), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24377))
-- Fix crash in `db:setup` when Elasticsearch is enabled ([rrgeorge](https://github.com/mastodon/mastodon/pull/24302))
-- Fix user archive takeout when using OpenStack Swift or S3 providers with no ACL support ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24200))
-- Fix invalid/expired invites being processed on sign-up ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24337))
-
-### Security
-
-- Update Ruby to 3.0.6 due to ReDoS vulnerabilities ([saizai](https://github.com/mastodon/mastodon/pull/24334))
-- Fix unescaped user input in LDAP query ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24379))
-
-## [4.1.1] - 2023-03-16
-
-### Added
-
-- Add redirection from paths with url-encoded `@` to their decoded form ([thijskh](https://github.com/mastodon/mastodon/pull/23593))
-- Add `lang` attribute to native language names in language picker in Web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23749))
-- Add headers to outgoing mails to avoid auto-replies ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23597))
-- Add support for refreshing many accounts at once with `tootctl accounts refresh` ([9p4](https://github.com/mastodon/mastodon/pull/23304))
-- Add confirmation modal when clicking to edit a post with a non-empty compose form ([PauloVilarinho](https://github.com/mastodon/mastodon/pull/23936))
-- Add support for the HAproxy PROXY protocol through the `PROXY_PROTO_V1` environment variable ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24064))
-- Add `SENDFILE_HEADER` environment variable ([Gargron](https://github.com/mastodon/mastodon/pull/24123))
-- Add cache headers to static files served through Rails ([Gargron](https://github.com/mastodon/mastodon/pull/24120))
-
-### Changed
-
-- Increase contrast of upload progress bar background ([toolmantim](https://github.com/mastodon/mastodon/pull/23836))
-- Change post auto-deletion throttling constants to better scale with server size ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23320))
-- Change order of bookmark and favourite sidebar entries in single-column UI for consistency ([TerryGarcia](https://github.com/mastodon/mastodon/pull/23701))
-- Change `ActivityPub::DeliveryWorker` retries to be spread out more ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21956))
-
-### Fixed
-
-- Fix “Remove all followers from the selected domains” also removing follows and notifications ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23805))
-- Fix streaming metrics format ([emilweth](https://github.com/mastodon/mastodon/pull/23519), [emilweth](https://github.com/mastodon/mastodon/pull/23520))
-- Fix case-sensitive check for previously used hashtags in hashtag autocompletion ([deanveloper](https://github.com/mastodon/mastodon/pull/23526))
-- Fix focus point of already-attached media not saving after edit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23566))
-- Fix sidebar behavior in settings/admin UI on mobile ([wxt2005](https://github.com/mastodon/mastodon/pull/23764))
-- Fix inefficiency when searching accounts per username in admin interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23801))
-- Fix duplicate “Publish” button on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23804))
-- Fix server error when failing to follow back followers from `/relationships` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23787))
-- Fix server error when attempting to display the edit history of a trendable post in the admin interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23574))
-- Fix `tootctl accounts migrate` crashing because of a typo ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23567))
-- Fix original account being unfollowed on migration before the follow request to the new account could be sent ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21957))
-- Fix the “Back” button in column headers sometimes leaving Mastodon ([c960657](https://github.com/mastodon/mastodon/pull/23953))
-- Fix pgBouncer resetting application name on every transaction ([Gargron](https://github.com/mastodon/mastodon/pull/23958))
-- Fix unconfirmed accounts being counted as active users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23803))
-- Fix `/api/v1/streaming` sub-paths not being redirected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23988))
-- Fix drag'n'drop upload area text that spans multiple lines not being centered ([vintprox](https://github.com/mastodon/mastodon/pull/24029))
-- Fix sidekiq jobs not triggering Elasticsearch index updates ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24046))
-- Fix tags being unnecessarily stripped from plain-text short site description ([c960657](https://github.com/mastodon/mastodon/pull/23975))
-- Fix HTML entities not being un-escaped in extracted plain-text from remote posts ([c960657](https://github.com/mastodon/mastodon/pull/24019))
-- Fix dashboard crash on ElasticSearch server error ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23751))
-- Fix incorrect post links in strikes when the account is remote ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23611))
-- Fix misleading error code when receiving invalid WebAuthn credentials ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23568))
-- Fix duplicate mails being sent when the SMTP server is too slow to close the connection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23750))
-
-### Security
-
-- Change user backups to use expiring URLs for download when possible ([Gargron](https://github.com/mastodon/mastodon/pull/24136))
-- Add warning for object storage misconfiguration ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24137))
-
-## [4.1.0] - 2023-02-10
-
-### Added
-
-- **Add support for importing/exporting server-wide domain blocks** ([enbylenore](https://github.com/mastodon/mastodon/pull/20597), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/21471), [dariusk](https://github.com/mastodon/mastodon/pull/22803), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/21470))
-- **Add listing of followed hashtags** ([connorshea](https://github.com/mastodon/mastodon/pull/21773))
-- **Add support for editing media description and focus point of already-sent posts** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20878))
- - Previously, you could add and remove attachments, but not edit media description of already-attached media
- - REST API changes:
- - `PUT /api/v1/statuses/:id` now takes an extra `media_attributes[]` array parameter with the `id` of the updated media and their updated `description`, `focus`, and `thumbnail`
-- **Add follow request banner on account header** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20785))
- - REST API changes:
- - `Relationship` entities have an extra `requested_by` boolean attribute representing whether the represented user has requested to follow you
-- **Add confirmation screen when handling reports** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22375), [Gargron](https://github.com/mastodon/mastodon/pull/23156), [tribela](https://github.com/mastodon/mastodon/pull/23178))
-- Add option to make the landing page be `/about` even when trends are enabled ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20808))
-- Add `noindex` setting back to the admin interface ([prplecake](https://github.com/mastodon/mastodon/pull/22205))
-- Add instance peers API endpoint toggle back to the admin interface ([dariusk](https://github.com/mastodon/mastodon/pull/22810))
-- Add instance activity API endpoint toggle back to the admin interface ([dariusk](https://github.com/mastodon/mastodon/pull/22833))
-- Add setting for status page URL ([Gargron](https://github.com/mastodon/mastodon/pull/23390), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23499))
- - REST API changes:
- - Add `configuration.urls.status` attribute to the object returned by `GET /api/v2/instance`
-- Add `account.approved` webhook ([Saiv46](https://github.com/mastodon/mastodon/pull/22938))
-- Add 12 hours option to polls ([Pleclown](https://github.com/mastodon/mastodon/pull/21131))
-- Add dropdown menu item to open admin interface for remote domains ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21895))
-- Add `--remove-headers`, `--prune-profiles` and `--include-follows` flags to `tootctl media remove` ([evanphilip](https://github.com/mastodon/mastodon/pull/22149))
-- Add `--email` and `--dry-run` options to `tootctl accounts delete` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22328))
-- Add `tootctl accounts migrate` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22330))
-- Add `tootctl accounts prune` ([tribela](https://github.com/mastodon/mastodon/pull/18397))
-- Add `tootctl domains purge` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22063))
-- Add `SIDEKIQ_CONCURRENCY` environment variable ([muffinista](https://github.com/mastodon/mastodon/pull/19589))
-- Add `DB_POOL` environment variable support for streaming server ([Gargron](https://github.com/mastodon/mastodon/pull/23470))
-- Add `MIN_THREADS` environment variable to set minimum Puma threads ([jimeh](https://github.com/mastodon/mastodon/pull/21048))
-- Add explanation text to log-in page ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20946))
-- Add user profile OpenGraph tag on post pages ([bramus](https://github.com/mastodon/mastodon/pull/21423))
-- Add maskable icon support for Android ([workeffortwaste](https://github.com/mastodon/mastodon/pull/20904))
-- Add Belarusian to supported languages ([Mixaill](https://github.com/mastodon/mastodon/pull/22022))
-- Add Western Frisian to supported languages ([ykzts](https://github.com/mastodon/mastodon/pull/18602))
-- Add Montenegrin to the language picker ([ayefries](https://github.com/mastodon/mastodon/pull/21013))
-- Add Southern Sami and Lule Sami to the language picker ([Jullan-M](https://github.com/mastodon/mastodon/pull/21262))
-- Add logging for Rails cache timeouts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21667))
-- Add color highlight for active hashtag “follow” button ([MFTabriz](https://github.com/mastodon/mastodon/pull/21629))
-- Add brotli compression to `assets:precompile` ([Izorkin](https://github.com/mastodon/mastodon/pull/19025))
-- Add “disabled” account filter to the `/admin/accounts` UI ([tribela](https://github.com/mastodon/mastodon/pull/21282))
-- Add transparency to modal background for accessibility ([edent](https://github.com/mastodon/mastodon/pull/18081))
-- Add `lang` attribute to image description textarea and poll option field ([c960657](https://github.com/mastodon/mastodon/pull/23293))
-- Add `spellcheck` attribute to Content Warning and poll option input fields ([c960657](https://github.com/mastodon/mastodon/pull/23395))
-- Add `title` attribute to video elements in media attachments ([bramus](https://github.com/mastodon/mastodon/pull/21420))
-- Add left and right margins to emojis ([dsblank](https://github.com/mastodon/mastodon/pull/20464))
-- Add `roles` attribute to `Account` entities in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23255), [tribela](https://github.com/mastodon/mastodon/pull/23428))
-- Add `reading:autoplay:gifs` to `/api/v1/preferences` ([j-f1](https://github.com/mastodon/mastodon/pull/22706))
-- Add `hide_collections` parameter to `/api/v1/accounts/credentials` ([CarlSchwan](https://github.com/mastodon/mastodon/pull/22790))
-- Add `policy` attribute to web push subscription objects in REST API at `/api/v1/push/subscriptions` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23210))
-- Add metrics endpoint to streaming API ([Gargron](https://github.com/mastodon/mastodon/pull/23388), [Gargron](https://github.com/mastodon/mastodon/pull/23469))
-- Add more specific error messages to HTTP signature verification ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21617))
-- Add Storj DCS to cloud object storage options in the `mastodon:setup` rake task ([jtolio](https://github.com/mastodon/mastodon/pull/21929))
-- Add checkmark symbol in the checkbox for sensitive media ([sidp](https://github.com/mastodon/mastodon/pull/22795))
-- Add missing accessibility attributes to logout link in modals ([kytta](https://github.com/mastodon/mastodon/pull/22549))
-- Add missing accessibility attributes to “Hide image” button in `MediaGallery` ([hs4man21](https://github.com/mastodon/mastodon/pull/22513))
-- Add missing accessibility attributes to hide content warning field when disabled ([hs4man21](https://github.com/mastodon/mastodon/pull/22568))
-- Add `aria-hidden` to footer circle dividers to improve accessibility ([hs4man21](https://github.com/mastodon/mastodon/pull/22576))
-- Add `lang` attribute to compose form inputs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23240))
-
-### Changed
-
-- **Ensure exact match is the first result in hashtag searches** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21315))
-- Change account search to return followed accounts first ([dariusk](https://github.com/mastodon/mastodon/pull/22956))
-- Change batch account suspension to create a strike ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20897))
-- Change default reply language to match the default language when replying to a translated post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22272))
-- Change misleading wording about waitlists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20850))
-- Increase width of the unread notification border ([connorshea](https://github.com/mastodon/mastodon/pull/21692))
-- Change new post notification button on profiles to make it more apparent when it is enabled ([tribela](https://github.com/mastodon/mastodon/pull/22541))
-- Change trending tags admin interface to always show batch action controls ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23013))
-- Change wording of some OAuth scope descriptions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22491))
-- Change wording of admin report handling actions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18388))
-- Change confirm prompts for relationships management ([tribela](https://github.com/mastodon/mastodon/pull/19411))
-- Change language surrounding disability in prompts for media descriptions ([hs4man21](https://github.com/mastodon/mastodon/pull/20923))
-- Change confusing wording in the sign in banner ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22490))
-- Change `POST /settings/applications/:id` to regenerate token on scopes change ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23359))
-- Change account moderation notes to make links clickable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22553))
-- Change link previews for statuses to never use avatar as fallback ([Gargron](https://github.com/mastodon/mastodon/pull/23376))
-- Change email address input to be read-only for logged-in users when requesting a new confirmation e-mail ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23247))
-- Change notifications per page from 15 to 40 in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/23348))
-- Change number of stored items in home feed from 400 to 800 ([Gargron](https://github.com/mastodon/mastodon/pull/23349))
-- Change API rate limits from 300/5min per user to 1500/5min per user, 300/5min per app ([Gargron](https://github.com/mastodon/mastodon/pull/23347))
-- Save avatar or header correctly even if the other one fails ([tribela](https://github.com/mastodon/mastodon/pull/18465))
-- Change `referrer-policy` to `same-origin` application-wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23037))
-- Add 'private' to `Cache-Control`, match Rails expectations ([daxtens](https://github.com/mastodon/mastodon/pull/20608))
-- Make the button that expands the compose form differentiable from the button that publishes a post ([Tak](https://github.com/mastodon/mastodon/pull/20864))
-- Change automatic post deletion configuration to be accessible to moved users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20774))
-- Make tag following idempotent ([trwnh](https://github.com/mastodon/mastodon/pull/20860), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/21285))
-- Use buildx functions for faster builds ([inductor](https://github.com/mastodon/mastodon/pull/20692))
-- Split off Dockerfile components for faster builds ([moritzheiber](https://github.com/mastodon/mastodon/pull/20933), [ineffyble](https://github.com/mastodon/mastodon/pull/20948), [BtbN](https://github.com/mastodon/mastodon/pull/21028))
-- Change last occurrence of “silence” to “limit” in UI text ([cincodenada](https://github.com/mastodon/mastodon/pull/20637))
-- Change “hide toot” to “hide post” ([seanthegeek](https://github.com/mastodon/mastodon/pull/22385))
-- Don't allow URLs that contain non-normalized paths to be verified ([dgl](https://github.com/mastodon/mastodon/pull/20999))
-- Change the “Trending now” header to be a link to the Explore page ([connorshea](https://github.com/mastodon/mastodon/pull/21759))
-- Change PostgreSQL connection timeout from 2 minutes to 15 seconds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21790))
-- Make handle more easily selectable on profile page ([cadars](https://github.com/mastodon/mastodon/pull/21479))
-- Allow admins to refresh remotely-suspended accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22327))
-- Change dropdown menu to contain “Copy link to post” even for non-public posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21316))
-- Allow adding relays in secure mode and limited federation mode ([ineffyble](https://github.com/mastodon/mastodon/pull/22324))
-- Change timestamps to be displayed using the user's timezone throughout the moderation interface ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/21878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22555))
-- Change CSP directives on API to be tight and concise ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20960))
-- Change web UI to not autofocus the compose form ([raboof](https://github.com/mastodon/mastodon/pull/16517), [Akkiesoft](https://github.com/mastodon/mastodon/pull/23094))
-- Change idempotency key handling for posting when database access is slow ([lambda](https://github.com/mastodon/mastodon/pull/21840))
-- Change remote media files to be downloaded outside of transactions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21796))
-- Improve contrast of charts in “poll has ended” notifications ([j-f1](https://github.com/mastodon/mastodon/pull/22575))
-- Change OEmbed detection and validation to be somewhat more lenient ([ineffyble](https://github.com/mastodon/mastodon/pull/22533))
-- Widen ElasticSearch version detection to not display a warning for OpenSearch ([VyrCossont](https://github.com/mastodon/mastodon/pull/22422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23064))
-- Change link verification to allow pages larger than 1MB as long as the link is in the first 1MB ([untitaker](https://github.com/mastodon/mastodon/pull/22879))
-- Update default Node.js version to Node.js 16 ([ineffyble](https://github.com/mastodon/mastodon/pull/22223), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22342))
-
-### Removed
-
-- Officially remove support for Ruby 2.6 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21477))
-- Remove `object-fit` polyfill used for old versions of Microsoft Edge ([shuuji3](https://github.com/mastodon/mastodon/pull/22693))
-- Remove `intersection-observer` polyfill for old Safari support ([shuuji3](https://github.com/mastodon/mastodon/pull/23284))
-- Remove empty `title` tag from mailer layout ([nametoolong](https://github.com/mastodon/mastodon/pull/23078))
-- Remove post count and last posts from ActivityPub representation of hashtag collections ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23460))
-
-### Fixed
-
-- **Fix changing domain block severity not undoing individual account effects** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22135))
-- Fix suspension worker crashing on S3-compatible setups without ACL support ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22487))
-- Fix possible race conditions when suspending/unsuspending accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22363))
-- Fix being stuck in edit mode when deleting the edited posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22126))
-- Fix attached media uploads not being cleared when replying to a post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23504))
-- Fix filters not being applied to some notification types ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23211))
-- Fix incorrect link in push notifications for some event types ([elizabeth-dev](https://github.com/mastodon/mastodon/pull/23286))
-- Fix some performance issues with `/admin/instances` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21907))
-- Fix some pre-4.0 admin audit logs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22091))
-- Fix moderation audit log items for warnings having incorrect links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23242))
-- Fix account activation being sometimes triggered before email confirmation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23245))
-- Fix missing OAuth scopes for admin APIs ([trwnh](https://github.com/mastodon/mastodon/pull/20918), [trwnh](https://github.com/mastodon/mastodon/pull/20979))
-- Fix voter count not being cleared when a poll is reset ([afontenot](https://github.com/mastodon/mastodon/pull/21700))
-- Fix attachments of edited posts not being fetched ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21565))
-- Fix irreversible and whole_word parameters handling in `/api/v1/filters` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21988))
-- Fix 500 error when marking posts as sensitive while some of them are deleted ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22134))
-- Fix expanded posts not always being scrolled into view ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21797))
-- Fix not being able to scroll the remote interaction modal on small screens ([xendke](https://github.com/mastodon/mastodon/pull/21763))
-- Fix not being able to scroll in post history modal ([cadars](https://github.com/mastodon/mastodon/pull/23396))
-- Fix audio player volume control on Safari ([minacle](https://github.com/mastodon/mastodon/pull/23187))
-- Fix disappearing “Explore” tabs on Safari ([nyura](https://github.com/mastodon/mastodon/pull/20917), [ykzts](https://github.com/mastodon/mastodon/pull/20982))
-- Fix wrong padding in RTL layout ([Gargron](https://github.com/mastodon/mastodon/pull/23157))
-- Fix drag & drop upload area display in single-column mode ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23217))
-- Fix being unable to get a single EmailDomainBlock from the admin API ([trwnh](https://github.com/mastodon/mastodon/pull/20846))
-- Fix admin-set follow recommandations being case-sensitive ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23500))
-- Fix unserialized `role` on account entities in admin API ([Gargron](https://github.com/mastodon/mastodon/pull/23290))
-- Fix pagination of followed tags ([trwnh](https://github.com/mastodon/mastodon/pull/20861))
-- Fix dropdown menu positions when scrolling ([sidp](https://github.com/mastodon/mastodon/pull/22916), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23062))
-- Fix email with empty domain name labels passing validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23246))
-- Fix mysterious registration failure when “Require a reason to join” is set with open registrations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22127))
-- Fix attachment rendering of edited posts in OpenGraph ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22270))
-- Fix invalid/empty RSS feed link on account pages ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20772))
-- Fix error in `VerifyLinkService` when processing links with no href ([joshuap](https://github.com/mastodon/mastodon/pull/20741))
-- Fix error in `VerifyLinkService` when processing links with invalid URLs ([untitaker](https://github.com/mastodon/mastodon/pull/23204))
-- Fix media uploads with FFmpeg 5 ([dead10ck](https://github.com/mastodon/mastodon/pull/21191))
-- Fix sensitive flag not being set when replying to a post with a content warning under certain conditions ([kedamaDQ](https://github.com/mastodon/mastodon/pull/21724))
-- Fix misleading message briefly showing up when loading follow requests under some conditions ([c960657](https://github.com/mastodon/mastodon/pull/23386))
-- Fix “Share @:user's profile” profile menu item not working ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21490))
-- Fix crash and incorrect behavior in `tootctl domains crawl` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19004))
-- Fix autoplay on iOS ([jamesadney](https://github.com/mastodon/mastodon/pull/21422))
-- Fix user clean-up scheduler crash when an unconfirmed account has a moderation note ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23318))
-- Fix spaces not being stripped in admin account search ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21324))
-- Fix spaces not being stripped when adding relays ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22655))
-- Fix infinite loading spinner instead of soft 404 for non-existing remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21303))
-- Fix minor visual issue with the top border of verified account fields ([j-f1](https://github.com/mastodon/mastodon/pull/22006))
-- Fix pending account approval and rejection not being recorded in the admin audit log ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/22088))
-- Fix “Sign up” button with closed registrations not opening modal on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22060))
-- Fix UI header overflowing on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21783))
-- Fix 500 error when trying to migrate to an invalid address ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21462))
-- Fix crash when trying to fetch unobtainable avatar of user using external authentication ([lochiiconnectivity](https://github.com/mastodon/mastodon/pull/22462))
-- Fix processing error on incoming malformed JSON-LD under some situations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23416))
-- Fix potential duplicate posts in Explore tab ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22121))
-- Fix deprecation warning in `tootctl accounts rotate` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22120))
-- Fix styling of featured tags in light theme ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23252))
-- Fix missing style in warning and strike cards ([AtelierSnek](https://github.com/mastodon/mastodon/pull/22177), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22302))
-- Fix wasteful request to `/api/v1/custom_emojis` when not logged in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22326))
-- Fix replies sometimes being delivered to user-blocked domains ([tribela](https://github.com/mastodon/mastodon/pull/22117))
-- Fix admin dashboard crash when using some ElasticSearch replacements ([cortices](https://github.com/mastodon/mastodon/pull/21006))
-- Fix profile avatar being slightly offset into left border ([RiedleroD](https://github.com/mastodon/mastodon/pull/20994))
-- Fix N+1 queries in `NotificationsController` ([nametoolong](https://github.com/mastodon/mastodon/pull/21202))
-- Fix being unable to react to announcements with the keycap number sign emoji ([kescherCode](https://github.com/mastodon/mastodon/pull/22231))
-- Fix height computation of post embeds ([hodgesmr](https://github.com/mastodon/mastodon/pull/22141))
-- Fix accessibility issue of the search bar due to hidden placeholder ([alexstine](https://github.com/mastodon/mastodon/pull/21275))
-- Fix layout change handler not being removed due to a typo ([nschonni](https://github.com/mastodon/mastodon/pull/21829))
-- Fix typo in the default `S3_HOSTNAME` used in the `mastodon:setup` rake task ([danp](https://github.com/mastodon/mastodon/pull/19932))
-- Fix the top action bar appearing in the multi-column layout ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20943))
-- Fix inability to use local LibreTranslate without setting `ALLOWED_PRIVATE_ADDRESSES` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21926))
-- Fix punycoded local domains not being prettified in initial state ([Tritlo](https://github.com/mastodon/mastodon/pull/21440))
-- Fix CSP violation warning by removing inline CSS from SVG logo ([luxiaba](https://github.com/mastodon/mastodon/pull/20814))
-- Fix margin for search field on medium window size ([minacle](https://github.com/mastodon/mastodon/pull/21606))
-- Fix search popout scrolling with the page in single-column mode ([rgroothuijsen](https://github.com/mastodon/mastodon/pull/16463))
-- Fix minor post cache hydration discrepancy ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19879))
-- Fix `・` detection in hashtags ([parthoghosh24](https://github.com/mastodon/mastodon/pull/22888))
-- Fix hashtag follows bypassing user blocks ([tribela](https://github.com/mastodon/mastodon/pull/22849))
-- Fix moved accounts being incorrectly redirected to account settings when trying to view a remote profile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22497))
-- Fix site upload validations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22479))
-- Fix “Add new domain block” button using last submitted search value instead of the current one ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22485))
-- Fix misleading hashtag warning when posting with “Followers only” or “Mentioned people only” visibility ([n0toose](https://github.com/mastodon/mastodon/pull/22827))
-- Fix embedded posts with videos grabbing focus ([Akkiesoft](https://github.com/mastodon/mastodon/pull/22778))
-- Fix `$` not being escaped in `.env.production` files generated by the `mastodon:setup` rake task ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23012), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23072))
-- Fix sanitizer parsing link text as HTML when stripping unsupported links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22558))
-- Fix `scheduled_at` input not using `datetime-local` when editing announcements ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21896))
-- Fix REST API serializer for `Account` not including `moved` when the moved account has itself moved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22483))
-- Fix `/api/v1/admin/trends/tags` using wrong serializer ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18943))
-- Fix situations in which instance actor can be set to a Mastodon-incompatible name ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22307))
-
-### Security
-
-- Add `form-action` CSP directive ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20781), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20958), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20962))
-- Fix unbounded recursion in account discovery ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22025))
-- Revoke all authorized applications on password reset ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/21325))
-- Fix unbounded recursion in post discovery ([ClearlyClaire,nametoolong](https://github.com/mastodon/mastodon/pull/23506))
-
-## [4.0.2] - 2022-11-15
-
-### Fixed
-
-- Fix wrong color on mentions hidden behind content warning in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20724))
-- Fix filters from other users being used in the streaming service ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20719))
-- Fix `unsafe-eval` being used when `wasm-unsafe-eval` is enough in Content Security Policy ([Gargron](https://github.com/mastodon/mastodon/pull/20729), [prplecake](https://github.com/mastodon/mastodon/pull/20606))
-
-## [4.0.1] - 2022-11-14
-
-### Fixed
-
-- Fix nodes order being sometimes mangled when rewriting emoji ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20677))
-
-## [4.0.0] - 2022-11-14
-
-Some of the features in this release have been funded through the [NGI0 Discovery](https://nlnet.nl/discovery) Fund, a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825322.
-
-### Added
-
-- Add ability to filter followed accounts' posts by language ([Gargron](https://github.com/mastodon/mastodon/pull/19095), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19268))
-- **Add ability to follow hashtags** ([Gargron](https://github.com/mastodon/mastodon/pull/18809), [Gargron](https://github.com/mastodon/mastodon/pull/18862), [Gargron](https://github.com/mastodon/mastodon/pull/19472), [noellabo](https://github.com/mastodon/mastodon/pull/18924))
-- Add ability to filter individual posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18945))
-- **Add ability to translate posts** ([Gargron](https://github.com/mastodon/mastodon/pull/19218), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19433), [Gargron](https://github.com/mastodon/mastodon/pull/19453), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19434), [Gargron](https://github.com/mastodon/mastodon/pull/19388), [ykzts](https://github.com/mastodon/mastodon/pull/19244), [Gargron](https://github.com/mastodon/mastodon/pull/19245))
-- Add featured tags to web UI ([noellabo](https://github.com/mastodon/mastodon/pull/19408), [noellabo](https://github.com/mastodon/mastodon/pull/19380), [noellabo](https://github.com/mastodon/mastodon/pull/19358), [noellabo](https://github.com/mastodon/mastodon/pull/19409), [Gargron](https://github.com/mastodon/mastodon/pull/19382), [ykzts](https://github.com/mastodon/mastodon/pull/19418), [noellabo](https://github.com/mastodon/mastodon/pull/19403), [noellabo](https://github.com/mastodon/mastodon/pull/19404), [Gargron](https://github.com/mastodon/mastodon/pull/19398), [Gargron](https://github.com/mastodon/mastodon/pull/19712), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20018))
-- **Add support for language preferences for trending statuses and links** ([Gargron](https://github.com/mastodon/mastodon/pull/18288), [Gargron](https://github.com/mastodon/mastodon/pull/19349), [ykzts](https://github.com/mastodon/mastodon/pull/19335))
- - Previously, you could only see trends in your current language
- - For less popular languages, that meant empty trends
- - Now, trends in your preferred languages' are shown on top, with others beneath
-- Add server rules to sign-up flow ([Gargron](https://github.com/mastodon/mastodon/pull/19296))
-- Add privacy icons to report modal in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19190))
-- Add `noopener` to links to remote profiles in web UI ([shleeable](https://github.com/mastodon/mastodon/pull/19014))
-- Add option to open original page in dropdowns of remote content in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20299))
-- Add warning for sensitive audio posts in web UI ([rgroothuijsen](https://github.com/mastodon/mastodon/pull/17885))
-- Add language attribute to posts in web UI ([tribela](https://github.com/mastodon/mastodon/pull/18544))
-- Add support for uploading WebP files ([Saiv46](https://github.com/mastodon/mastodon/pull/18506))
-- Add support for uploading `audio/vnd.wave` files ([tribela](https://github.com/mastodon/mastodon/pull/18737))
-- Add support for uploading AVIF files ([txt-file](https://github.com/mastodon/mastodon/pull/19647))
-- Add support for uploading HEIC files ([Gargron](https://github.com/mastodon/mastodon/pull/19618))
-- Add more debug information when processing remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/15605), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19209))
-- **Add retention policy for cached content and media** ([Gargron](https://github.com/mastodon/mastodon/pull/19232), [zunda](https://github.com/mastodon/mastodon/pull/19478), [Gargron](https://github.com/mastodon/mastodon/pull/19458), [Gargron](https://github.com/mastodon/mastodon/pull/19248))
- - Set for how long remote posts or media should be cached on your server
- - Hands-off alternative to `tootctl` commands
-- **Add customizable user roles** ([Gargron](https://github.com/mastodon/mastodon/pull/18641), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18812), [Gargron](https://github.com/mastodon/mastodon/pull/19040), [tribela](https://github.com/mastodon/mastodon/pull/18825), [tribela](https://github.com/mastodon/mastodon/pull/18826), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18776), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18777), [unextro](https://github.com/mastodon/mastodon/pull/18786), [tribela](https://github.com/mastodon/mastodon/pull/18824), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19436))
- - Previously, there were 3 hard-coded roles, user, moderator, and admin
- - Create your own roles and decide which permissions they should have
-- Add notifications for new reports ([Gargron](https://github.com/mastodon/mastodon/pull/18697), [Gargron](https://github.com/mastodon/mastodon/pull/19475))
-- Add ability to select all accounts matching search for batch actions in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19053), [Gargron](https://github.com/mastodon/mastodon/pull/19054))
-- Add ability to view previous edits of a status in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19462))
-- Add ability to block sign-ups from IP ([Gargron](https://github.com/mastodon/mastodon/pull/19037))
-- **Add webhooks to admin UI** ([Gargron](https://github.com/mastodon/mastodon/pull/18510))
-- Add admin API for managing domain allows ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18668))
-- Add admin API for managing domain blocks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18247))
-- Add admin API for managing e-mail domain blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19066))
-- Add admin API for managing canonical e-mail blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19067))
-- Add admin API for managing IP blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19065), [trwnh](https://github.com/mastodon/mastodon/pull/20207))
-- Add `sensitized` attribute to accounts in admin REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20094))
-- Add `services` and `metadata` to the NodeInfo endpoint ([MFTabriz](https://github.com/mastodon/mastodon/pull/18563))
-- Add `--remove-role` option to `tootctl accounts modify` ([Gargron](https://github.com/mastodon/mastodon/pull/19477))
-- Add `--days` option to `tootctl media refresh` ([tribela](https://github.com/mastodon/mastodon/pull/18425))
-- Add `EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION` environment variable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18642))
-- Add `IP_RETENTION_PERIOD` and `SESSION_RETENTION_PERIOD` environment variables ([kescherCode](https://github.com/mastodon/mastodon/pull/18757))
-- Add `http_hidden_proxy` environment variable ([tribela](https://github.com/mastodon/mastodon/pull/18427))
-- Add `ENABLE_STARTTLS` environment variable ([erbridge](https://github.com/mastodon/mastodon/pull/20321))
-- Add caching for payload serialization during fan-out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19637), [Gargron](https://github.com/mastodon/mastodon/pull/19642), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19746), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19747), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19963))
-- Add assets from Twemoji 14.0 ([Gargron](https://github.com/mastodon/mastodon/pull/19733))
-- Add reputation and followers score boost to SQL-only account search ([Gargron](https://github.com/mastodon/mastodon/pull/19251))
-- Add Scots, Balaibalan, Láadan, Lingua Franca Nova, Lojban, Toki Pona to languages list ([VyrCossont](https://github.com/mastodon/mastodon/pull/20168))
-- Set autocomplete hints for e-mail, password and OTP fields ([rcombs](https://github.com/mastodon/mastodon/pull/19833), [offbyone](https://github.com/mastodon/mastodon/pull/19946), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20071))
-- Add support for DigitalOcean Spaces in setup wizard ([v-aisac](https://github.com/mastodon/mastodon/pull/20573))
-
-### Changed
-
-- **Change brand color and logotypes** ([Gargron](https://github.com/mastodon/mastodon/pull/18592), [Gargron](https://github.com/mastodon/mastodon/pull/18639), [Gargron](https://github.com/mastodon/mastodon/pull/18691), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18634), [Gargron](https://github.com/mastodon/mastodon/pull/19254), [mayaeh](https://github.com/mastodon/mastodon/pull/18710))
-- **Change post editing to be enabled in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/19103))
-- **Change web UI to work for logged-out users** ([Gargron](https://github.com/mastodon/mastodon/pull/18961), [Gargron](https://github.com/mastodon/mastodon/pull/19250), [Gargron](https://github.com/mastodon/mastodon/pull/19294), [Gargron](https://github.com/mastodon/mastodon/pull/19306), [Gargron](https://github.com/mastodon/mastodon/pull/19315), [ykzts](https://github.com/mastodon/mastodon/pull/19322), [Gargron](https://github.com/mastodon/mastodon/pull/19412), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19437), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19415), [Gargron](https://github.com/mastodon/mastodon/pull/19348), [Gargron](https://github.com/mastodon/mastodon/pull/19295), [Gargron](https://github.com/mastodon/mastodon/pull/19422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19414), [Gargron](https://github.com/mastodon/mastodon/pull/19319), [Gargron](https://github.com/mastodon/mastodon/pull/19345), [Gargron](https://github.com/mastodon/mastodon/pull/19310), [Gargron](https://github.com/mastodon/mastodon/pull/19301), [Gargron](https://github.com/mastodon/mastodon/pull/19423), [ykzts](https://github.com/mastodon/mastodon/pull/19471), [ykzts](https://github.com/mastodon/mastodon/pull/19333), [ykzts](https://github.com/mastodon/mastodon/pull/19337), [ykzts](https://github.com/mastodon/mastodon/pull/19272), [ykzts](https://github.com/mastodon/mastodon/pull/19468), [Gargron](https://github.com/mastodon/mastodon/pull/19466), [Gargron](https://github.com/mastodon/mastodon/pull/19457), [Gargron](https://github.com/mastodon/mastodon/pull/19426), [Gargron](https://github.com/mastodon/mastodon/pull/19427), [Gargron](https://github.com/mastodon/mastodon/pull/19421), [Gargron](https://github.com/mastodon/mastodon/pull/19417), [Gargron](https://github.com/mastodon/mastodon/pull/19413), [Gargron](https://github.com/mastodon/mastodon/pull/19397), [Gargron](https://github.com/mastodon/mastodon/pull/19387), [Gargron](https://github.com/mastodon/mastodon/pull/19396), [Gargron](https://github.com/mastodon/mastodon/pull/19385), [ykzts](https://github.com/mastodon/mastodon/pull/19334), [ykzts](https://github.com/mastodon/mastodon/pull/19329), [Gargron](https://github.com/mastodon/mastodon/pull/19324), [Gargron](https://github.com/mastodon/mastodon/pull/19318), [Gargron](https://github.com/mastodon/mastodon/pull/19316), [Gargron](https://github.com/mastodon/mastodon/pull/19263), [trwnh](https://github.com/mastodon/mastodon/pull/19305), [ykzts](https://github.com/mastodon/mastodon/pull/19273), [Gargron](https://github.com/mastodon/mastodon/pull/19801), [Gargron](https://github.com/mastodon/mastodon/pull/19790), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19773), [Gargron](https://github.com/mastodon/mastodon/pull/19798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19724), [Gargron](https://github.com/mastodon/mastodon/pull/19709), [Gargron](https://github.com/mastodon/mastodon/pull/19514), [Gargron](https://github.com/mastodon/mastodon/pull/19562), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19981), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19978), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20148), [Gargron](https://github.com/mastodon/mastodon/pull/20302), [cutls](https://github.com/mastodon/mastodon/pull/20400))
- - The web app can now be accessed without being logged in
- - No more `/web` prefix on web app paths
- - Profiles, posts, and other public pages now use the same interface for logged in and logged out users
- - The web app displays a server information banner
- - Pop-up windows for remote interaction have been replaced with a modal window
- - No need to type in your username for remote interaction, copy-paste-to-search method explained
- - Various hints throughout the app explain what the different timelines are
- - New about page design
- - New privacy policy page design shows when the policy was last updated
- - All sections of the web app now have appropriate window titles
- - The layout of the interface has been streamlined between different screen sizes
- - Posts now use more horizontal space
-- Change label of publish button to be "Publish" again in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/18583))
-- Change language to be carried over on reply in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18557))
-- Change "Unfollow" to "Cancel follow request" when request still pending in web UI ([prplecake](https://github.com/mastodon/mastodon/pull/19363))
-- **Change post filtering system** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18058), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19050), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18894), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19051), [noellabo](https://github.com/mastodon/mastodon/pull/18923), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18744), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20567))
- - Filtered keywords and phrases can now be grouped into named categories
- - Filtered posts show which exact filter was hit
- - Individual posts can be added to a filter
- - You can peek inside filtered posts anyway
-- Change path of privacy policy page from `/terms` to `/privacy-policy` ([Gargron](https://github.com/mastodon/mastodon/pull/19249))
-- Change how hashtags are normalized ([Gargron](https://github.com/mastodon/mastodon/pull/18795), [Gargron](https://github.com/mastodon/mastodon/pull/18863), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18854))
-- Change settings area to be separated into categories in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19407), [Gargron](https://github.com/mastodon/mastodon/pull/19533))
-- Change "No accounts selected" errors to use the appropriate noun in admin UI ([prplecake](https://github.com/mastodon/mastodon/pull/19356))
-- Change e-mail domain blocks to match subdomains of blocked domains ([Gargron](https://github.com/mastodon/mastodon/pull/18979))
-- Change custom emoji file size limit from 50 KB to 256 KB ([Gargron](https://github.com/mastodon/mastodon/pull/18788))
-- Change "Allow trends without prior review" setting to also work for trending posts ([Gargron](https://github.com/mastodon/mastodon/pull/17977))
-- Change admin announcements form to use single inputs for date and time in admin UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18321))
-- Change search API to be accessible without being logged in ([Gargron](https://github.com/mastodon/mastodon/pull/18963), [Gargron](https://github.com/mastodon/mastodon/pull/19326))
-- Change following and followers API to be accessible without being logged in ([Gargron](https://github.com/mastodon/mastodon/pull/18964))
-- Change `AUTHORIZED_FETCH` to not block unauthenticated REST API access ([Gargron](https://github.com/mastodon/mastodon/pull/19803))
-- Change Helm configuration ([deepy](https://github.com/mastodon/mastodon/pull/18997), [jgsmith](https://github.com/mastodon/mastodon/pull/18415), [deepy](https://github.com/mastodon/mastodon/pull/18941))
-- Change mentions of blocked users to not be processed ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19725))
-- Change max. thumbnail dimensions to 640x360px (360p) ([Gargron](https://github.com/mastodon/mastodon/pull/19619))
-- Change post-processing to be deferred only for large media types ([Gargron](https://github.com/mastodon/mastodon/pull/19617))
-- Change link verification to only work for https links without unicode ([Gargron](https://github.com/mastodon/mastodon/pull/20304), [Gargron](https://github.com/mastodon/mastodon/pull/20295))
-- Change account deletion requests to spread out over time ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20222))
-- Change larger reblogs/favourites numbers to be shortened in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20303))
-- Change incoming activity processing to happen in `ingress` queue ([Gargron](https://github.com/mastodon/mastodon/pull/20264))
-- Change notifications to not link show preview cards in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20335))
-- Change amount of replies returned for logged out users in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20355))
-- Change in-app links to keep you in-app in web UI ([trwnh](https://github.com/mastodon/mastodon/pull/20540), [Gargron](https://github.com/mastodon/mastodon/pull/20628))
-- Change table header to be sticky in admin UI ([sk22](https://github.com/mastodon/mastodon/pull/20442))
-
-### Removed
-
-- Remove setting that disables account deletes ([Gargron](https://github.com/mastodon/mastodon/pull/17683))
-- Remove digest e-mails ([Gargron](https://github.com/mastodon/mastodon/pull/17985))
-- Remove unnecessary sections from welcome e-mail ([Gargron](https://github.com/mastodon/mastodon/pull/19299))
-- Remove item titles from RSS feeds ([Gargron](https://github.com/mastodon/mastodon/pull/18640))
-- Remove volume number from hashtags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19253))
-- Remove Nanobox configuration ([tonyjiang](https://github.com/mastodon/mastodon/pull/17881))
-
-### Fixed
-
-- Fix rules with same priority being sorted non-deterministically ([Gargron](https://github.com/mastodon/mastodon/pull/20623))
-- Fix error when invalid domain name is submitted ([Gargron](https://github.com/mastodon/mastodon/pull/19474))
-- Fix icons having an image role ([Gargron](https://github.com/mastodon/mastodon/pull/20600))
-- Fix connections to IPv6-only servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20108))
-- Fix unnecessary service worker registration and preloading when logged out in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20341))
-- Fix unnecessary and slow regex construction ([raggi](https://github.com/mastodon/mastodon/pull/20215))
-- Fix `mailers` queue not being used for mailers ([Gargron](https://github.com/mastodon/mastodon/pull/20274))
-- Fix error in webfinger redirect handling ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20260))
-- Fix report category not being set to `violation` if rule IDs are provided ([trwnh](https://github.com/mastodon/mastodon/pull/20137))
-- Fix nodeinfo metadata attribute being an array instead of an object ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20114))
-- Fix account endorsements not being idempotent ([trwnh](https://github.com/mastodon/mastodon/pull/20118))
-- Fix status and rule IDs not being strings in admin reports REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20122))
-- Fix error on invalid `replies_policy` in REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20126))
-- Fix redrafting a currently-editing post not leaving edit mode in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20023))
-- Fix performance by avoiding method cache busts ([raggi](https://github.com/mastodon/mastodon/pull/19957))
-- Fix opening the language picker scrolling the single-column view to the top in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19983))
-- Fix content warning button missing `aria-expanded` attribute in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19975))
-- Fix redundant `aria-pressed` attributes in web UI ([Brawaru](https://github.com/mastodon/mastodon/pull/19912))
-- Fix crash when external auth provider has no display name set ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19962))
-- Fix followers count not being updated when migrating follows ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19998))
-- Fix double button to clear emoji search input in web UI ([sunny](https://github.com/mastodon/mastodon/pull/19888))
-- Fix missing null check on applications on strike disputes ([kescherCode](https://github.com/mastodon/mastodon/pull/19851))
-- Fix featured tags not saving preferred casing ([Gargron](https://github.com/mastodon/mastodon/pull/19732))
-- Fix language not being saved when editing status ([Gargron](https://github.com/mastodon/mastodon/pull/19543))
-- Fix not being able to input featured tag with hash symbol ([Gargron](https://github.com/mastodon/mastodon/pull/19535))
-- Fix user clean-up scheduler crash when an unconfirmed account has a moderation note ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19629))
-- Fix being unable to withdraw follow request when confirmation modal is disabled in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19687))
-- Fix inaccurate admin log entry for re-sending confirmation e-mails ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19674))
-- Fix edits not being immediately reflected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19673))
-- Fix bookmark import stopping at the first failure ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19669))
-- Fix account action type validation ([Gargron](https://github.com/mastodon/mastodon/pull/19476))
-- Fix upload progress not communicating processing phase in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19530))
-- Fix wrong host being used for custom.css when asset host configured ([Gargron](https://github.com/mastodon/mastodon/pull/19521))
-- Fix account migration form ever using outdated account data ([Gargron](https://github.com/mastodon/mastodon/pull/18429), [nightpool](https://github.com/mastodon/mastodon/pull/19883))
-- Fix error when uploading malformed CSV import ([Gargron](https://github.com/mastodon/mastodon/pull/19509))
-- Fix avatars not using image tags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19488))
-- Fix handling of duplicate and out-of-order notifications in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19693))
-- Fix reblogs being discarded after the reblogged status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19731))
-- Fix indexing scheduler trying to index when Elasticsearch is disabled ([Gargron](https://github.com/mastodon/mastodon/pull/19805))
-- Fix n+1 queries when rendering initial state JSON ([Gargron](https://github.com/mastodon/mastodon/pull/19795))
-- Fix n+1 query during status removal ([Gargron](https://github.com/mastodon/mastodon/pull/19753))
-- Fix OCR not working due to Content Security Policy in web UI ([prplecake](https://github.com/mastodon/mastodon/pull/18817))
-- Fix `nofollow` rel being removed in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19455))
-- Fix language dropdown causing zoom on mobile devices in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19428))
-- Fix button to dismiss suggestions not showing up in search results in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19325))
-- Fix language dropdown sometimes not appearing in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19246))
-- Fix quickly switching notification filters resulting in empty or incorrect list in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19052), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18960))
-- Fix media modal link button in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18877))
-- Fix error upon successful account migration ([Gargron](https://github.com/mastodon/mastodon/pull/19386))
-- Fix negatives values in search index causing queries to fail ([Gargron](https://github.com/mastodon/mastodon/pull/19464), [Gargron](https://github.com/mastodon/mastodon/pull/19481))
-- Fix error when searching for invalid URL ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18580))
-- Fix IP blocks not having a unique index ([Gargron](https://github.com/mastodon/mastodon/pull/19456))
-- Fix remote account in contact account setting not being used ([Gargron](https://github.com/mastodon/mastodon/pull/19351))
-- Fix swallowing mentions of unconfirmed/unapproved users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19191))
-- Fix incorrect and slow cache invalidation when blocking domain and removing media attachments ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19062))
-- Fix HTTPs redirect behaviour when running as I2P service ([gi-yt](https://github.com/mastodon/mastodon/pull/18929))
-- Fix deleted pinned posts potentially counting towards the pinned posts limit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19005))
-- Fix compatibility with OpenSSL 3.0 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18449))
-- Fix error when a remote report includes a private post the server has no access to ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18760))
-- Fix suspicious sign-in mails never being sent ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18599))
-- Fix fallback locale when somehow user's locale is an empty string ([tribela](https://github.com/mastodon/mastodon/pull/18543))
-- Fix avatar/header not being deleted locally when deleted on remote account ([tribela](https://github.com/mastodon/mastodon/pull/18973))
-- Fix missing `,` in Blurhash validation ([noellabo](https://github.com/mastodon/mastodon/pull/18660))
-- Fix order by most recent not working for relationships page in admin UI ([tribela](https://github.com/mastodon/mastodon/pull/18996))
-- Fix uncaught error when invalid date is supplied to API ([Gargron](https://github.com/mastodon/mastodon/pull/19480))
-- Fix REST API sometimes returning HTML on error ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19135))
-- Fix ambiguous column names in `tootctl media refresh` ([tribela](https://github.com/mastodon/mastodon/pull/19206))
-- Fix ambiguous column names in `tootctl search deploy` ([mashirozx](https://github.com/mastodon/mastodon/pull/18993))
-- Fix `CDN_HOST` not being used in some asset URLs ([tribela](https://github.com/mastodon/mastodon/pull/18662))
-- Fix `CAS_DISPLAY_NAME`, `SAML_DISPLAY_NAME` and `OIDC_DISPLAY_NAME` being ignored ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18568))
-- Fix various typos in comments throughout the codebase ([luzpaz](https://github.com/mastodon/mastodon/pull/18604))
-- Fix CSV import error when rows include unicode characters ([HamptonMakes](https://github.com/mastodon/mastodon/pull/20592))
-
-### Security
-
-- Fix being able to spoof link verification ([Gargron](https://github.com/mastodon/mastodon/pull/20217))
-- Fix emoji substitution not applying only to text nodes in backend code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20641))
-- Fix emoji substitution not applying only to text nodes in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20640))
-- Fix rate limiting for paths with formats ([Gargron](https://github.com/mastodon/mastodon/pull/20675))
-- Fix out-of-bound reads in blurhash transcoder ([delroth](https://github.com/mastodon/mastodon/pull/20388))
-
-_For previous changes, review the [stable-3.5 branch](https://github.com/mastodon/mastodon/blob/stable-3.5/CHANGELOG.md)_
+- Applied changes to emoji reactions PR on glitch-soc
diff --git a/CHANGELOG_glitch.md b/CHANGELOG_glitch.md
new file mode 100644
index 0000000000..a53790afaf
--- /dev/null
+++ b/CHANGELOG_glitch.md
@@ -0,0 +1,1036 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## [4.2.7] - 2024-02-16
+
+### Fixed
+
+- Fix OmniAuth tests and edge cases in error handling ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29201), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/29207))
+- Fix new installs by upgrading to the latest release of the `nsa` gem, instead of a no longer existing commit ([mjankowski](https://github.com/mastodon/mastodon/pull/29065))
+
+### Security
+
+- Fix insufficient checking of remote posts ([GHSA-jhrq-qvrm-qr36](https://github.com/mastodon/mastodon/security/advisories/GHSA-jhrq-qvrm-qr36))
+
+## [4.2.6] - 2024-02-14
+
+### Security
+
+- Update the `sidekiq-unique-jobs` dependency (see [GHSA-cmh9-rx85-xj38](https://github.com/mhenrixon/sidekiq-unique-jobs/security/advisories/GHSA-cmh9-rx85-xj38))
+ In addition, we have disabled the web interface for `sidekiq-unique-jobs` out of caution.
+ If you need it, you can re-enable it by setting `ENABLE_SIDEKIQ_UNIQUE_JOBS_UI=true`.
+ If you only need to clear all locks, you can now use `bundle exec rake sidekiq_unique_jobs:delete_all_locks`.
+- Update the `nokogiri` dependency (see [GHSA-xc9x-jj77-9p9j](https://github.com/sparklemotion/nokogiri/security/advisories/GHSA-xc9x-jj77-9p9j))
+- Disable administrative Doorkeeper routes ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/29187))
+- Fix ongoing streaming sessions not being invalidated when applications get deleted in some cases ([GHSA-7w3c-p9j8-mq3x](https://github.com/mastodon/mastodon/security/advisories/GHSA-7w3c-p9j8-mq3x))
+ In some rare cases, the streaming server was not notified of access tokens revocation on application deletion.
+- Change external authentication behavior to never reattach a new identity to an existing user by default ([GHSA-vm39-j3vx-pch3](https://github.com/mastodon/mastodon/security/advisories/GHSA-vm39-j3vx-pch3))
+ Up until now, Mastodon has allowed new identities from external authentication providers to attach to an existing local user based on their verified e-mail address.
+ This allowed upgrading users from a database-stored password to an external authentication provider, or move from one authentication provider to another.
+ However, this behavior may be unexpected, and means that when multiple authentication providers are configured, the overall security would be that of the least secure authentication provider.
+ For these reasons, this behavior is now locked under the `ALLOW_UNSAFE_AUTH_PROVIDER_REATTACH` environment variable.
+ In addition, regardless of this environment variable, Mastodon will refuse to attach two identities from the same authentication provider to the same account.
+
+## [4.2.5] - 2024-02-01
+
+### Security
+
+- Fix insufficient origin validation (CVE-2024-23832, [GHSA-3fjr-858r-92rw](https://github.com/mastodon/mastodon/security/advisories/GHSA-3fjr-858r-92rw))
+
+## [4.2.4] - 2024-01-24
+
+### Fixed
+
+- Fix error when processing remote files with unusually long names ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28823))
+- Fix processing of compacted single-item JSON-LD collections ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28816))
+- Retry 401 errors on replies fetching ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/28788))
+- Fix `RecordNotUnique` errors in LinkCrawlWorker ([tribela](https://github.com/mastodon/mastodon/pull/28748))
+- Fix Mastodon not correctly processing HTTP Signatures with query strings ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28443), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/28476))
+- Fix potential redirection loop of streaming endpoint ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28665))
+- Fix streaming API redirection ignoring the port of `streaming_api_base_url` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28558))
+- Fix error when processing link preview with an array as `inLanguage` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28252))
+- Fix unsupported time zone or locale preventing sign-up ([Gargron](https://github.com/mastodon/mastodon/pull/28035))
+- Fix "Hide these posts from home" list setting not refreshing when switching lists ([brianholley](https://github.com/mastodon/mastodon/pull/27763))
+- Fix missing background behind dismissable banner in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/27479))
+- Fix line wrapping of language selection button with long locale codes ([gunchleoc](https://github.com/mastodon/mastodon/pull/27100), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27127))
+- Fix `Undo Announce` activity not being sent to non-follower authors ([MitarashiDango](https://github.com/mastodon/mastodon/pull/18482))
+- Fix N+1s because of association preloaders not actually getting called ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28339))
+- Fix empty column explainer getting cropped under certain conditions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28337))
+- Fix `LinkCrawlWorker` error when encountering empty OEmbed response ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28268))
+- Fix call to inefficient `delete_matched` cache method in domain blocks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28367))
+
+### Security
+
+- Add rate-limit of TOTP authentication attempts at controller level ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28801))
+
+## [4.2.3] - 2023-12-05
+
+### Fixed
+
+- Fix dependency on `json-canonicalization` version that has been made unavailable since last release
+
+## [4.2.2] - 2023-12-04
+
+### Changed
+
+- Change dismissed banners to be stored server-side ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27055))
+- Change GIF max matrix size error to explicitly mention GIF files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27927))
+- Change `Follow` activities delivery to bypass availability check ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/27586))
+- Change single-column navigation notice to be displayed outside of the logo container ([renchap](https://github.com/mastodon/mastodon/pull/27462), [renchap](https://github.com/mastodon/mastodon/pull/27476))
+- Change Content-Security-Policy to be tighter on media paths ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26889))
+- Change post language code to include country code when relevant ([gunchleoc](https://github.com/mastodon/mastodon/pull/27099), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27207))
+
+### Fixed
+
+- Fix upper border radius of onboarding columns ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27890))
+- Fix incoming status creation date not being restricted to standard ISO8601 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27655), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/28081))
+- Fix some posts from threads received out-of-order sometimes not being inserted into timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27653))
+- Fix posts from force-sensitized accounts being able to trend ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27620))
+- Fix error when trying to delete already-deleted file with OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27569))
+- Fix batch attachment deletion when using OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27554))
+- Fix processing LDSigned activities from actors with unknown public keys ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27474))
+- Fix error and incorrect URLs in `/api/v1/accounts/:id/featured_tags` for remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27459))
+- Fix report processing notice not mentioning the report number when performing a custom action ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27442))
+- Fix handling of `inLanguage` attribute in preview card processing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27423))
+- Fix own posts being removed from home timeline when unfollowing a used hashtag ([kmycode](https://github.com/mastodon/mastodon/pull/27391))
+- Fix some link anchors being recognized as hashtags ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27271), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27584))
+- Fix format-dependent redirects being cached regardless of requested format ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27634))
+
+## [4.2.1] - 2023-10-10
+
+### Added
+
+- Add redirection on `/deck` URLs for logged-out users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27128))
+- Add support for v4.2.0 migrations to `tootctl maintenance fix-duplicates` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27147))
+
+### Changed
+
+- Change some worker lock TTLs to be shorter-lived ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27246))
+- Change user archive export allowed period from 7 days to 6 days ([suddjian](https://github.com/mastodon/mastodon/pull/27200))
+
+### Fixed
+
+- Fix duplicate reports being sent when reporting some remote posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27355))
+- Fix clicking on already-opened thread post scrolling to the top of the thread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27331), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27338), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27350))
+- Fix some remote posts getting truncated ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27307))
+- Fix some cases of infinite scroll code trying to fetch inaccessible posts in a loop ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27286))
+- Fix `Vary` headers not being set on some redirects ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27272))
+- Fix mentions being matched in some URL query strings ([mjankowski](https://github.com/mastodon/mastodon/pull/25656))
+- Fix unexpected linebreak in version string in the Web UI ([vmstan](https://github.com/mastodon/mastodon/pull/26986))
+- Fix double scroll bars in some columns in advanced interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27187))
+- Fix boosts of local users being filtered in account timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27204))
+- Fix multiple instances of the trend refresh scheduler sometimes running at once ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27253))
+- Fix importer returning negative row estimates ([jgillich](https://github.com/mastodon/mastodon/pull/27258))
+- Fix incorrectly keeping outdated update notices absent from the API endpoint ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27021))
+- Fix import progress not updating on certain failures ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27247))
+- Fix websocket connections being incorrectly decremented twice on errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/27238))
+- Fix explore prompt appearing because of posts being received out of order ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27211))
+- Fix explore prompt sometimes showing up when the home TL is loading ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27062))
+- Fix link handling of mentions in user profiles when logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27185))
+- Fix filtering audit log for entries about disabling 2FA ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27186))
+- Fix notification toasts not respecting reduce-motion ([c960657](https://github.com/mastodon/mastodon/pull/27178))
+- Fix retention dashboard not displaying correct month ([vmstan](https://github.com/mastodon/mastodon/pull/27180))
+- Fix tIME chunk not being properly removed from PNG uploads ([TheEssem](https://github.com/mastodon/mastodon/pull/27111))
+- Fix division by zero in video in bitrate computation code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27129))
+- Fix inefficient queries in “Follows and followers” as well as several admin pages ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27116), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27306))
+- Fix ActiveRecord using two connection pools when no replica is defined ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27061))
+- Fix the search documentation URL in system checks ([renchap](https://github.com/mastodon/mastodon/pull/27036))
+
+## [4.2.0] - 2023-09-21
+
+The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by [@danielmbrasil](https://github.com/danielmbrasil), [@mjankowski](https://github.com/mjankowski), [@nschonni](https://github.com/nschonni), [@renchap](https://github.com/renchap), and [@takayamaki](https://github.com/takayamaki).
+
+### Added
+
+- **Add full-text search of opted-in public posts and rework search operators** ([Gargron](https://github.com/mastodon/mastodon/pull/26485), [jsgoldstein](https://github.com/mastodon/mastodon/pull/26344), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26657), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26650), [jsgoldstein](https://github.com/mastodon/mastodon/pull/26659), [Gargron](https://github.com/mastodon/mastodon/pull/26660), [Gargron](https://github.com/mastodon/mastodon/pull/26663), [Gargron](https://github.com/mastodon/mastodon/pull/26688), [Gargron](https://github.com/mastodon/mastodon/pull/26689), [Gargron](https://github.com/mastodon/mastodon/pull/26686), [Gargron](https://github.com/mastodon/mastodon/pull/26687), [Gargron](https://github.com/mastodon/mastodon/pull/26692), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26697), [Gargron](https://github.com/mastodon/mastodon/pull/26699), [Gargron](https://github.com/mastodon/mastodon/pull/26701), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26710), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26739), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26754), [Gargron](https://github.com/mastodon/mastodon/pull/26662), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26755), [Gargron](https://github.com/mastodon/mastodon/pull/26781), [Gargron](https://github.com/mastodon/mastodon/pull/26782), [Gargron](https://github.com/mastodon/mastodon/pull/26760), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26756), [Gargron](https://github.com/mastodon/mastodon/pull/26784), [Gargron](https://github.com/mastodon/mastodon/pull/26807), [Gargron](https://github.com/mastodon/mastodon/pull/26835), [Gargron](https://github.com/mastodon/mastodon/pull/26847), [Gargron](https://github.com/mastodon/mastodon/pull/26834), [arbolitoloco1](https://github.com/mastodon/mastodon/pull/26893), [tribela](https://github.com/mastodon/mastodon/pull/26896), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26927), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26959), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27014))
+ This introduces a new `public_statuses` Elasticsearch index for public posts by users who have opted in to their posts being searchable (`toot#indexable` flag).
+ This also revisits the other indexes to provide more useful indexing, and adds new search operators such as `from:me`, `before:2022-11-01`, `after:2022-11-01`, `during:2022-11-01`, `language:fr`, `has:poll`, or `in:library` (for searching only in posts you have written or interacted with).
+ Results are now ordered chronologically.
+- **Add admin notifications for new Mastodon versions** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26582))
+ This is done by querying `https://api.joinmastodon.org/update-check` every 30 minutes in a background job.
+ That URL can be changed using the `UPDATE_CHECK_URL` environment variable, and the feature outright disabled by setting that variable to an empty string (`UPDATE_CHECK_URL=`).
+- **Add “Privacy and reach” tab in profile settings** ([Gargron](https://github.com/mastodon/mastodon/pull/26484), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26508))
+ This reorganized scattered privacy and reach settings to a single place, as well as improve their wording.
+- **Add display of out-of-band hashtags in the web interface** ([Gargron](https://github.com/mastodon/mastodon/pull/26492), [arbolitoloco1](https://github.com/mastodon/mastodon/pull/26497), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26506), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26525), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26606), [Gargron](https://github.com/mastodon/mastodon/pull/26666), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26960))
+- **Add role badges to the web interface** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25649), [Gargron](https://github.com/mastodon/mastodon/pull/26281))
+- **Add ability to pick domains to forward reports to using the `forward_to_domains` parameter in `POST /api/v1/reports`** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25866), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26636))
+ The `forward_to_domains` REST API parameter is a list of strings. If it is empty or omitted, the previous behavior is maintained.
+ The `forward` parameter still needs to be set for `forward_to_domains` to be taken into account.
+ The forwarded-to domains can only include that of the original author and people being replied to.
+- **Add forwarding of reported replies to servers being replied to** ([Gargron](https://github.com/mastodon/mastodon/pull/25341), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26189))
+- Add `ONE_CLICK_SSO_LOGIN` environment variable to directly link to the Single-Sign On provider if there is only one sign up method available ([CSDUMMI](https://github.com/mastodon/mastodon/pull/26083), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26368), [CSDUMMI](https://github.com/mastodon/mastodon/pull/26857), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26901))
+- **Add webhook templating** ([Gargron](https://github.com/mastodon/mastodon/pull/23289))
+- **Add webhooks for local `status.created`, `status.updated`, `account.updated` and `report.updated`** ([VyrCossont](https://github.com/mastodon/mastodon/pull/24133), [VyrCossont](https://github.com/mastodon/mastodon/pull/24243), [VyrCossont](https://github.com/mastodon/mastodon/pull/24211))
+- **Add exclusive lists** ([dariusk, necropolina](https://github.com/mastodon/mastodon/pull/22048), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25324))
+- **Add a confirmation screen when suspending a domain** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25144), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25603))
+- **Add support for importing lists** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25203), [mgmn](https://github.com/mastodon/mastodon/pull/26120), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26372))
+- **Add optional hCaptcha support** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25019), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25057), [Gargron](https://github.com/mastodon/mastodon/pull/25395), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26388))
+- **Add lines to threads in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24549), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24677), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24696), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24711), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24714), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24713), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24715), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24800), [teeerevor](https://github.com/mastodon/mastodon/pull/25706), [renchap](https://github.com/mastodon/mastodon/pull/25807))
+- **Add new onboarding flow to web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24619), [Gargron](https://github.com/mastodon/mastodon/pull/24646), [Gargron](https://github.com/mastodon/mastodon/pull/24705), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24872), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/24883), [Gargron](https://github.com/mastodon/mastodon/pull/24954), [stevenjlm](https://github.com/mastodon/mastodon/pull/24959), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25010), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25275), [Gargron](https://github.com/mastodon/mastodon/pull/25559), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25561))
+- **Add auto-refresh of accounts we get new messages/edits of** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26510))
+- **Add Elasticsearch cluster health check and indexes mismatch check to dashboard** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26448), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26605), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26658))
+- Add `hide_collections`, `discoverable` and `indexable` attributes to credentials API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26998))
+- Add `S3_ENABLE_CHECKSUM_MODE` environment variable to enable checksum verification on compatible S3-providers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26435))
+- Add admin API for managing tags ([rrgeorge](https://github.com/mastodon/mastodon/pull/26872))
+- Add a link to hashtag timelines from the Trending hashtags moderation interface ([gunchleoc](https://github.com/mastodon/mastodon/pull/26724))
+- Add timezone to datetimes in e-mails ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26822))
+- Add `authorized_fetch` server setting in addition to env var ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26958))
+- Add avatar image to webfinger responses ([tvler](https://github.com/mastodon/mastodon/pull/26558))
+- Add debug logging on signature verification failure ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26637), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26812))
+- Add explicit error messages when DeepL quota is exceeded ([lutoma](https://github.com/mastodon/mastodon/pull/26704))
+- Add Elasticsearch/OpenSearch version to “Software” in admin dashboard ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26652))
+- Add `data-nosnippet` attribute to remote posts and local posts with `noindex` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26648))
+- Add support for federating `memorial` attribute ([rrgeorge](https://github.com/mastodon/mastodon/pull/26583))
+- Add Cherokee and Kalmyk to languages dropdown ([gunchleoc](https://github.com/mastodon/mastodon/pull/26012), [gunchleoc](https://github.com/mastodon/mastodon/pull/26013))
+- Add `DELETE /api/v1/profile/avatar` and `DELETE /api/v1/profile/header` to the REST API ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25124), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26573))
+- Add `ES_PRESET` option to customize numbers of shards and replicas ([Gargron](https://github.com/mastodon/mastodon/pull/26483), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26489))
+ This can have a value of `single_node_cluster` (default), `small_cluster` (uses one replica) or `large_cluster` (uses one replica and a higher number of shards).
+- Add `CACHE_BUSTER_HTTP_METHOD` environment variable ([renchap](https://github.com/mastodon/mastodon/pull/26528), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26542))
+- Add support for `DB_PASS` when using `DATABASE_URL` ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26295))
+- Add `GET /api/v1/instance/languages` to REST API ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24443))
+- Add primary key to `preview_cards_statuses` join table ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25243), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26384), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26447), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26737), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26979))
+- Add client-side timeout on resend confirmation button ([Gargron](https://github.com/mastodon/mastodon/pull/26300))
+- Add published date and author to news on the explore screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26155))
+- Add `lang` attribute to various UI components ([c960657](https://github.com/mastodon/mastodon/pull/23869), [c960657](https://github.com/mastodon/mastodon/pull/23891), [c960657](https://github.com/mastodon/mastodon/pull/26111), [c960657](https://github.com/mastodon/mastodon/pull/26149))
+- Add stricter protocol fields validation for accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25937))
+- Add support for Azure blob storage ([mistydemeo](https://github.com/mastodon/mastodon/pull/23607), [mistydemeo](https://github.com/mastodon/mastodon/pull/26080))
+- Add toast with option to open post after publishing in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25564), [Signez](https://github.com/mastodon/mastodon/pull/25919), [Gargron](https://github.com/mastodon/mastodon/pull/26664))
+- Add canonical link tags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25715))
+- Add button to see results for polls in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25726))
+- Add at-symbol prepended to mention span title ([forsamori](https://github.com/mastodon/mastodon/pull/25684))
+- Add users index on `unconfirmed_email` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25672), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25702))
+- Add superapp index on `oauth_applications` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25670))
+- Add index to backups on `user_id` column ([mjankowski](https://github.com/mastodon/mastodon/pull/25647))
+- Add onboarding prompt when home feed too slow in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25267), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25556), [Gargron](https://github.com/mastodon/mastodon/pull/25579), [renchap](https://github.com/mastodon/mastodon/pull/25580), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25581), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25617), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25917), [Gargron](https://github.com/mastodon/mastodon/pull/26829), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26935))
+- Add `POST /api/v1/conversations/:id/unread` API endpoint to mark a conversation as unread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25509))
+- Add `translate="no"` to outgoing mentions and links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25524))
+- Add unsubscribe link and headers to e-mails ([Gargron](https://github.com/mastodon/mastodon/pull/25378), [c960657](https://github.com/mastodon/mastodon/pull/26085))
+- Add logging of websocket send errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25280))
+- Add time zone preference ([Gargron](https://github.com/mastodon/mastodon/pull/25342), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26025))
+- Add `legal` as report category ([Gargron](https://github.com/mastodon/mastodon/pull/23941), [renchap](https://github.com/mastodon/mastodon/pull/25400), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26509))
+- Add `data-nosnippet` so Google doesn't use trending posts in snippets for `/` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25279))
+- Add card with who invited you to join when displaying rules on sign-up ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23475))
+- Add missing primary keys to `accounts_tags` and `statuses_tags` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25210))
+- Add support for custom sign-up URLs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25014), [renchap](https://github.com/mastodon/mastodon/pull/25108), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25190), [mgmn](https://github.com/mastodon/mastodon/pull/25531))
+ This is set using `SSO_ACCOUNT_SIGN_UP` and reflected in the REST API by adding `registrations.sign_up_url` to the `/api/v2/instance` endpoint.
+- Add polling and automatic redirection to `/start` on email confirmation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25013))
+- Add ability to block sign-ups from IP using the CLI ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24870))
+- Add ALT badges to media that has alternative text in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24782), [c960657](https://github.com/mastodon/mastodon/pull/26166)
+- Add ability to include accounts with pending follow requests in lists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19727), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24810))
+- Add trend management to admin API ([rrgeorge](https://github.com/mastodon/mastodon/pull/24257))
+ - `POST /api/v1/admin/trends/statuses/:id/approve`
+ - `POST /api/v1/admin/trends/statuses/:id/reject`
+ - `POST /api/v1/admin/trends/links/:id/approve`
+ - `POST /api/v1/admin/trends/links/:id/reject`
+ - `POST /api/v1/admin/trends/tags/:id/approve`
+ - `POST /api/v1/admin/trends/tags/:id/reject`
+ - `GET /api/v1/admin/trends/links/publishers`
+ - `POST /api/v1/admin/trends/links/publishers/:id/approve`
+ - `POST /api/v1/admin/trends/links/publishers/:id/reject`
+- Add user handle to notification mail recipient address ([HeitorMC](https://github.com/mastodon/mastodon/pull/24240))
+- Add progress indicator to sign-up flow ([Gargron](https://github.com/mastodon/mastodon/pull/24545))
+- Add client-side validation for taken username in sign-up form ([Gargron](https://github.com/mastodon/mastodon/pull/24546))
+- Add `--approve` option to `tootctl accounts create` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24533))
+- Add “In Memoriam” banner back to profiles ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23591), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23614))
+ This adds the `memorial` attribute to the `Account` REST API entity.
+- Add colour to follow button when hashtag is being followed ([c960657](https://github.com/mastodon/mastodon/pull/24361))
+- Add further explanations to the profile link verification instructions ([drzax](https://github.com/mastodon/mastodon/pull/19723))
+- Add a link to Identity provider's account settings from the account settings ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24100), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24628))
+- Add support for streaming server to connect to postgres with self-signed certs through the `sslmode` URL parameter ([ramuuns](https://github.com/mastodon/mastodon/pull/21431))
+- Add support for specifying S3 storage classes through the `S3_STORAGE_CLASS` environment variable ([hyl](https://github.com/mastodon/mastodon/pull/22480))
+- Add support for incoming rich text ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23913))
+- Add support for Ruby 3.2 ([tenderlove](https://github.com/mastodon/mastodon/pull/22928), [casperisfine](https://github.com/mastodon/mastodon/pull/24142), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24202), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26934))
+- Add API parameter to safeguard unexpected mentions in new posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18350))
+
+### Changed
+
+- **Change hashtags to be displayed separately when they are the last line of a post** ([renchap](https://github.com/mastodon/mastodon/pull/26499), [renchap](https://github.com/mastodon/mastodon/pull/26614), [renchap](https://github.com/mastodon/mastodon/pull/26615))
+- **Change reblogs to be excluded from "Posts and replies" tab in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/26302))
+- **Change interaction modal in web interface** ([Gargron, ClearlyClaire](https://github.com/mastodon/mastodon/pull/26075), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26269), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26268), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26267), [mgmn](https://github.com/mastodon/mastodon/pull/26459), [tribela](https://github.com/mastodon/mastodon/pull/26461), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26593), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26795))
+- **Change design of link previews in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/26136), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26151), [Gargron](https://github.com/mastodon/mastodon/pull/26153), [Gargron](https://github.com/mastodon/mastodon/pull/26250), [Gargron](https://github.com/mastodon/mastodon/pull/26287), [Gargron](https://github.com/mastodon/mastodon/pull/26286), [c960657](https://github.com/mastodon/mastodon/pull/26184))
+- **Change "direct message" nomenclature to "private mention" in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/24248))
+- **Change translation feature to cover Content Warnings, poll options and media descriptions** ([c960657](https://github.com/mastodon/mastodon/pull/24175), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/25251), [c960657](https://github.com/mastodon/mastodon/pull/26168), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26452))
+- **Change account search to match by text when opted-in** ([jsgoldstein](https://github.com/mastodon/mastodon/pull/25599), [Gargron](https://github.com/mastodon/mastodon/pull/26378))
+- **Change import feature to be clearer, less error-prone and more reliable** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21054), [mgmn](https://github.com/mastodon/mastodon/pull/24874))
+- **Change local and federated timelines to be tabs of a single “Live feeds” column** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25641), [Gargron](https://github.com/mastodon/mastodon/pull/25683), [mgmn](https://github.com/mastodon/mastodon/pull/25694), [Plastikmensch](https://github.com/mastodon/mastodon/pull/26247), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26633))
+- **Change user archive export to be faster and more reliable, and export `.zip` archives instead of `.tar.gz` ones** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23360), [TheEssem](https://github.com/mastodon/mastodon/pull/25034))
+- **Change `mastodon-streaming` systemd unit files to be templated** ([e-nomem](https://github.com/mastodon/mastodon/pull/24751))
+- **Change `statsd` integration to disable sidekiq metrics by default** ([mjankowski](https://github.com/mastodon/mastodon/pull/25265), [mjankowski](https://github.com/mastodon/mastodon/pull/25336), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26310))
+ This deprecates `statsd` support and disables the sidekiq integration unless `STATSD_SIDEKIQ` is set to `true`.
+ This is because the `nsa` gem is unmaintained, and its sidekiq integration is known to add very significant overhead.
+ Later versions of Mastodon will have other ways to get the same metrics.
+- **Change replica support to native Rails adapter** ([krainboltgreene](https://github.com/mastodon/mastodon/pull/25693), [Gargron](https://github.com/mastodon/mastodon/pull/25849), [Gargron](https://github.com/mastodon/mastodon/pull/25874), [Gargron](https://github.com/mastodon/mastodon/pull/25851), [Gargron](https://github.com/mastodon/mastodon/pull/25977), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26074), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26326), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26386), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26856))
+ This is a breaking change, dropping `makara` support, and requiring you to update your database configuration if you are using replicas.
+ To tell Mastodon to use a read replica, you can either set the `REPLICA_DB_NAME` environment variable (along with `REPLICA_DB_USER`, `REPLICA_DB_PASS`, `REPLICA_DB_HOST`, and `REPLICA_DB_PORT`, if they differ from the primary database), or the `REPLICA_DATABASE_URL` environment variable if your configuration is based on `DATABASE_URL`.
+- Change DCT method used for JPEG encoding to float ([electroCutie](https://github.com/mastodon/mastodon/pull/26675))
+- Change from `node-redis` to `ioredis` for streaming ([gmemstr](https://github.com/mastodon/mastodon/pull/26581))
+- Change private statuses index to index without crutches ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26713))
+- Change video compression parameters ([Gargron](https://github.com/mastodon/mastodon/pull/26631), [Gargron](https://github.com/mastodon/mastodon/pull/26745), [Gargron](https://github.com/mastodon/mastodon/pull/26766), [Gargron](https://github.com/mastodon/mastodon/pull/26970))
+- Change admin e-mail notification settings to be their own settings group ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26596))
+- Change opacity of the delete icon in the search field to be more visible ([AntoninDelFabbro](https://github.com/mastodon/mastodon/pull/26449))
+- Change Account Search to prioritize username over display name ([jsgoldstein](https://github.com/mastodon/mastodon/pull/26623))
+- Change follow recommendation materialized view to be faster in most cases ([renchap, ClearlyClaire](https://github.com/mastodon/mastodon/pull/26545))
+- Change `robots.txt` to block GPTBot ([Foritus](https://github.com/mastodon/mastodon/pull/26396))
+- Change header of hashtag timelines in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26362), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26416))
+- Change streaming `/metrics` to include additional metrics ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26299), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26945))
+- Change indexing frequency from 5 minutes to 1 minute, add locks to schedulers ([Gargron](https://github.com/mastodon/mastodon/pull/26304))
+- Change column link to add a better keyboard focus indicator ([teeerevor](https://github.com/mastodon/mastodon/pull/26278))
+- Change poll form element colors to fit with the rest of the ui ([teeerevor](https://github.com/mastodon/mastodon/pull/26139), [teeerevor](https://github.com/mastodon/mastodon/pull/26162), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26164))
+- Change 'favourite' to 'favorite' for American English ([marekr](https://github.com/mastodon/mastodon/pull/24667), [gunchleoc](https://github.com/mastodon/mastodon/pull/26009), [nabijaczleweli](https://github.com/mastodon/mastodon/pull/26109))
+- Change ActivityStreams representation of suspended accounts to not use a blank `name` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25276))
+- Change focus UI for keyboard only input ([teeerevor](https://github.com/mastodon/mastodon/pull/25935), [Gargron](https://github.com/mastodon/mastodon/pull/26125), [Gargron](https://github.com/mastodon/mastodon/pull/26767))
+- Change thread view to scroll to the selected post rather than the post being replied to ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24685))
+- Change links in multi-column mode so tabs are open in single-column mode ([Signez](https://github.com/mastodon/mastodon/pull/25893), [Signez](https://github.com/mastodon/mastodon/pull/26070), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25973), [Signez](https://github.com/mastodon/mastodon/pull/26019), [Signez](https://github.com/mastodon/mastodon/pull/26759))
+- Change searching with `#` to include account index ([jsgoldstein](https://github.com/mastodon/mastodon/pull/25638))
+- Change label and design of sensitive and unavailable media in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25712), [Gargron](https://github.com/mastodon/mastodon/pull/26135), [Gargron](https://github.com/mastodon/mastodon/pull/26330))
+- Change button colors to increase hover/focus contrast and consistency ([teeerevor](https://github.com/mastodon/mastodon/pull/25677), [Gargron](https://github.com/mastodon/mastodon/pull/25679))
+- Change dropdown icon above compose form from ellipsis to bars in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25661))
+- Change header backgrounds to use fewer different colors in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25577))
+- Change files to be deleted in batches instead of one-by-one ([Gargron](https://github.com/mastodon/mastodon/pull/23302), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/25586), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25587))
+- Change emoji picker icon ([iparr](https://github.com/mastodon/mastodon/pull/25479))
+- Change edit profile page ([Gargron](https://github.com/mastodon/mastodon/pull/25413), [c960657](https://github.com/mastodon/mastodon/pull/26538))
+- Change "bot" label to "automated" ([Gargron](https://github.com/mastodon/mastodon/pull/25356))
+- Change design of dropdowns in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25107))
+- Change wording of “Content cache retention period” setting to highlight destructive implications ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23261))
+- Change autolinking to allow carets in URL search params ([renchap](https://github.com/mastodon/mastodon/pull/25216))
+- Change share action from being in action bar to being in dropdown in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25105))
+- Change sessions to be ordered from most-recent to least-recently updated ([frankieroberto](https://github.com/mastodon/mastodon/pull/25005))
+- Change vacuum scheduler to also delete expired tokens and unused application records ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24868), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24871))
+- Change "Sign in" to "Login" ([Gargron](https://github.com/mastodon/mastodon/pull/24942))
+- Change domain suspensions to also be checked before trying to fetch unknown remote resources ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24535))
+- Change media components to use aspect-ratio rather than compute height themselves ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24686), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24943), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26801))
+- Change logo version in header based on screen size in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24707))
+- Change label from "For you" to "People" on explore screen in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24706))
+- Change logged-out WebUI HTML pages to be cached for a few seconds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24708))
+- Change unauthenticated responses to be cached in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/24348), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24662), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24665))
+- Change HTTP caching logic ([Gargron](https://github.com/mastodon/mastodon/pull/24347), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24604))
+- Change hashtags and mentions in bios to open in-app in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24643))
+- Change styling of the recommended accounts to allow bio to be more visible ([chike00](https://github.com/mastodon/mastodon/pull/24480))
+- Change account search in moderation interface to allow searching by username including the leading `@` ([HeitorMC](https://github.com/mastodon/mastodon/pull/24242))
+- Change all components to use the same error page in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24512))
+- Change search pop-out in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24305))
+- Change user settings to be stored in a more optimal way ([Gargron](https://github.com/mastodon/mastodon/pull/23630), [c960657](https://github.com/mastodon/mastodon/pull/24321), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24453), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24460), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24558), [Gargron](https://github.com/mastodon/mastodon/pull/24761), [Gargron](https://github.com/mastodon/mastodon/pull/24783), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25508), [jsgoldstein](https://github.com/mastodon/mastodon/pull/25340), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26884), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27012))
+- Change media upload limits and remove client-side resizing ([Gargron](https://github.com/mastodon/mastodon/pull/23726))
+- Change design of account rows in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24247), [Gargron](https://github.com/mastodon/mastodon/pull/24343), [Gargron](https://github.com/mastodon/mastodon/pull/24956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25131))
+- Change log-out to use Single Logout when using external log-in through OIDC ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24020))
+- Change sidekiq-bulk's batch size from 10,000 to 1,000 jobs in one Redis call ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24034))
+- Change translation to only be offered for supported languages ([c960657](https://github.com/mastodon/mastodon/pull/23879), [c960657](https://github.com/mastodon/mastodon/pull/24037))
+ This adds the `/api/v1/instance/translation_languages` REST API endpoint that returns an object with the supported translation language pairs in the form:
+ ```json
+ {
+ "fr": ["en", "de"]
+ }
+ ```
+ (where `fr` is a supported source language and `en` and `de` or supported output language when translating a `fr` string)
+- Change compose form checkbox to native input with `appearance: none` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22949))
+- Change posts' clickable area to be larger ([c960657](https://github.com/mastodon/mastodon/pull/23621))
+- Change `followed_by` link to `location=all` if account is local on /admin/accounts/:id page ([tribela](https://github.com/mastodon/mastodon/pull/23467))
+
+### Removed
+
+- **Remove support for Node.js 14** ([renchap](https://github.com/mastodon/mastodon/pull/25198))
+- **Remove support for Ruby 2.7** ([nschonni](https://github.com/mastodon/mastodon/pull/24237))
+- **Remove clustering from streaming API** ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/24655))
+- **Remove anonymous access to the streaming API** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23989))
+- Remove obfuscation of reply count in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26768))
+- Remove `kmr` from language selection, as it was a duplicate for `ku` ([gunchleoc](https://github.com/mastodon/mastodon/pull/26014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26787))
+- Remove 16:9 cropping from web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26132))
+- Remove back button from bookmarks, favourites and lists screens in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26126))
+- Remove display name input from sign-up form ([Gargron](https://github.com/mastodon/mastodon/pull/24704))
+- Remove `tai` locale ([c960657](https://github.com/mastodon/mastodon/pull/23880))
+- Remove empty Kushubian (csb) local files ([nschonni](https://github.com/mastodon/mastodon/pull/24151))
+- Remove `Permissions-Policy` header from all responses ([Gargron](https://github.com/mastodon/mastodon/pull/24124))
+
+### Fixed
+
+- **Fix filters not being applying in the explore page** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25887))
+- **Fix being unable to load past a full page of filtered posts in Home timeline** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24930))
+- **Fix log-in flow when involving both OAuth and external authentication** ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24073))
+- **Fix broken links in account gallery** ([c960657](https://github.com/mastodon/mastodon/pull/24218))
+- **Fix migration handler not updating lists** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24808))
+- Fix crash when viewing a moderation appeal and the moderator account has been deleted ([xrobau](https://github.com/mastodon/mastodon/pull/25900))
+- Fix error in Web UI when server rules cannot be fetched ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26957))
+- Fix paragraph margins resulting in irregular read-more cut-off in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26828))
+- Fix notification permissions being requested immediately after login ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26472))
+- Fix performances of profile directory ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26840), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26842))
+- Fix mute button and volume slider feeling disconnected in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26827), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26860))
+- Fix “Scoped order is ignored, it's forced to be batch order.” warnings ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26793))
+- Fix blocked domain appearing in account feeds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26823))
+- Fix invalid `Content-Type` header for WebP images ([c960657](https://github.com/mastodon/mastodon/pull/26773))
+- Fix minor inefficiencies in `tootctl search deploy` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26721))
+- Fix filter form in profiles directory overflowing instead of wrapping ([arbolitoloco1](https://github.com/mastodon/mastodon/pull/26682))
+- Fix sign up steps progress layout in right-to-left locales ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26728))
+- Fix bug with “favorited by” and “reblogged by“ view on posts only showing up to 40 items ([timothyjrogers](https://github.com/mastodon/mastodon/pull/26577), [timothyjrogers](https://github.com/mastodon/mastodon/pull/26574))
+- Fix bad search type heuristic ([Gargron](https://github.com/mastodon/mastodon/pull/26673))
+- Fix not being able to negate prefix clauses in search ([Gargron](https://github.com/mastodon/mastodon/pull/26672))
+- Fix timeout on invalid set of exclusionary parameters in `/api/v1/timelines/public` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/26239))
+- Fix adding column with default value taking longer on Postgres >= 11 ([Gargron](https://github.com/mastodon/mastodon/pull/26375))
+- Fix light theme select option for hashtags ([teeerevor](https://github.com/mastodon/mastodon/pull/26311))
+- Fix AVIF attachments ([c960657](https://github.com/mastodon/mastodon/pull/26264))
+- Fix incorrect URL normalization when fetching remote resources ([c960657](https://github.com/mastodon/mastodon/pull/26219), [c960657](https://github.com/mastodon/mastodon/pull/26285))
+- Fix being unable to filter posts for individual Chinese languages ([gunchleoc](https://github.com/mastodon/mastodon/pull/26066))
+- Fix preview card sometimes linking to 4xx error pages ([c960657](https://github.com/mastodon/mastodon/pull/26200))
+- Fix emoji picker button scrolling with textarea content in single-column view ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25304))
+- Fix missing border on error screen in light theme in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/26152))
+- Fix UI overlap with the loupe icon in the Explore Tab ([gol-cha](https://github.com/mastodon/mastodon/pull/26113))
+- Fix unexpected redirection to `/explore` after sign-in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26143))
+- Fix `/api/v1/statuses/:id/unfavourite` and `/api/v1/statuses/:id/unreblog` returning non-updated counts ([c960657](https://github.com/mastodon/mastodon/pull/24365))
+- Fix clicking the “Back” button sometimes leading out of Mastodon ([c960657](https://github.com/mastodon/mastodon/pull/23953), [CSFlorin](https://github.com/mastodon/mastodon/pull/24835), [S-H-GAMELINKS](https://github.com/mastodon/mastodon/pull/24867), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25281))
+- Fix processing of `null` ActivityPub activities ([tribela](https://github.com/mastodon/mastodon/pull/26021))
+- Fix hashtag posts not being removed from home feed on hashtag unfollow ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26028))
+- Fix for "follows you" indicator in light web UI not readable ([vmstan](https://github.com/mastodon/mastodon/pull/25993))
+- Fix incorrect line break between icon and number of reposts & favourites ([edent](https://github.com/mastodon/mastodon/pull/26004))
+- Fix sounds not being loaded from assets host ([Signez](https://github.com/mastodon/mastodon/pull/25931))
+- Fix buttons showing inconsistent styles ([teeerevor](https://github.com/mastodon/mastodon/pull/25903), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25965), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26341), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/26482))
+- Fix trend calculation working on too many items at a time ([Gargron](https://github.com/mastodon/mastodon/pull/25835))
+- Fix dropdowns being disabled for logged out users in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25714), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25964))
+- Fix explore page being inaccessible when opted-out of trends in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25716))
+- Fix re-activated accounts possibly getting deleted by `AccountDeletionWorker` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25711))
+- Fix `/api/v2/search` not working with following query param ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25681))
+- Fix inefficient query when requesting a new confirmation email from a logged-in account ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25669))
+- Fix unnecessary concurrent calls to `/api/*/instance` in web UI ([mgmn](https://github.com/mastodon/mastodon/pull/25663))
+- Fix resolving local URL for remote content ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25637))
+- Fix search not being easily findable on smaller screens in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25576), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25631))
+- Fix j/k keyboard shortcuts on some status lists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25554))
+- Fix missing validation on `default_privacy` setting ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25513))
+- Fix incorrect pagination headers in `/api/v2/admin/accounts` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25477))
+- Fix non-interactive upload container being given a `button` role and tabIndex ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25462))
+- Fix always redirecting to onboarding in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/25396))
+- Fix inconsistent use of middle dot (·) instead of bullet (•) to separate items ([j-f1](https://github.com/mastodon/mastodon/pull/25248))
+- Fix spacing of middle dots in the detailed status meta section ([j-f1](https://github.com/mastodon/mastodon/pull/25247))
+- Fix prev/next buttons color in media viewer ([renchap](https://github.com/mastodon/mastodon/pull/25231))
+- Fix email addresses not being properly updated in `tootctl maintenance fix-duplicates` ([mjankowski](https://github.com/mastodon/mastodon/pull/25118))
+- Fix unicode surrogate pairs sometimes being broken in page title ([eai04191](https://github.com/mastodon/mastodon/pull/25148))
+- Fix various inefficient queries against account domains ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25126))
+- Fix video player offering to expand in a lightbox when it's in an `iframe` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25067))
+- Fix post embed previews ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25071))
+- Fix inadequate error handling in several API controllers when given invalid parameters ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24947), [danielmbrasil](https://github.com/mastodon/mastodon/pull/24958), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25063), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25072), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25386), [danielmbrasil](https://github.com/mastodon/mastodon/pull/25595))
+- Fix uncaught `ActiveRecord::StatementInvalid` in Mastodon::IpBlocksCLI ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24861))
+- Fix various edge cases with local moves ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24812))
+- Fix `tootctl accounts cull` crashing when encountering a domain resolving to a private address ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23378))
+- Fix `tootctl accounts approve --number N` not aproving the N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605))
+- Fix being unable to clear media description when editing posts ([c960657](https://github.com/mastodon/mastodon/pull/24720))
+- Fix unavailable translations not falling back to English ([mgmn](https://github.com/mastodon/mastodon/pull/24727))
+- Fix anonymous visitors getting a session cookie on first visit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24584), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24650), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24664))
+- Fix cutting off first letter of hashtag links sometimes in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/24623))
+- Fix crash in `tootctl accounts create --reattach --force` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24557), [danielmbrasil](https://github.com/mastodon/mastodon/pull/24680))
+- Fix characters being emojified even when using Variation Selector 15 (text) ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20949), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24615))
+- Fix uncaught ActiveRecord::StatementInvalid exception in `Mastodon::AccountsCLI#approve` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24590))
+- Fix email confirmation skip option in `tootctl accounts modify USERNAME --email EMAIL --confirm` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24578))
+- Fix tooltip for dates without time ([c960657](https://github.com/mastodon/mastodon/pull/24244))
+- Fix missing loading spinner and loading more on scroll in Private Mentions column ([c960657](https://github.com/mastodon/mastodon/pull/24446))
+- Fix account header image missing from `/settings/profile` on narrow screens ([c960657](https://github.com/mastodon/mastodon/pull/24433))
+- Fix height of announcements not being updated when using reduced animations ([c960657](https://github.com/mastodon/mastodon/pull/24354))
+- Fix inconsistent radius in advanced interface drawer ([thislight](https://github.com/mastodon/mastodon/pull/24407))
+- Fix loading more trending posts on scroll in the advanced interface ([OmmyZhang](https://github.com/mastodon/mastodon/pull/24314))
+- Fix poll ending notification for edited polls ([c960657](https://github.com/mastodon/mastodon/pull/24311))
+- Fix max width of media in `/about` and `/privacy-policy` ([mgmn](https://github.com/mastodon/mastodon/pull/24180))
+- Fix streaming API not being usable without `DATABASE_URL` ([Gargron](https://github.com/mastodon/mastodon/pull/23960))
+- Fix external authentication not running onboarding code for new users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23458))
+
+## [4.1.8] - 2023-09-19
+
+### Fixed
+
+- Fix post edits not being forwarded as expected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26936))
+- Fix moderator rights inconsistencies ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26729))
+- Fix crash when encountering invalid URL ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26814))
+- Fix cached posts including stale stats ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26409))
+- Fix uploading of video files for which `ffprobe` reports `0/0` average framerate ([NicolaiSoeborg](https://github.com/mastodon/mastodon/pull/26500))
+- Fix unexpected audio stream transcoding when uploaded video is eligible to passthrough ([yufushiro](https://github.com/mastodon/mastodon/pull/26608))
+
+### Security
+
+- Fix missing HTML sanitization in translation API (CVE-2023-42452, [GHSA-2693-xr3m-jhqr](https://github.com/mastodon/mastodon/security/advisories/GHSA-2693-xr3m-jhqr))
+- Fix incorrect domain name normalization (CVE-2023-42451, [GHSA-v3xf-c9qf-j667](https://github.com/mastodon/mastodon/security/advisories/GHSA-v3xf-c9qf-j667))
+
+## [4.1.7] - 2023-09-05
+
+### Changed
+
+- Change remote report processing to accept reports with long comments, but truncate them ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25028))
+
+### Fixed
+
+- **Fix blocking subdomains of an already-blocked domain** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26392))
+- Fix `/api/v1/timelines/tag/:hashtag` allowing for unauthenticated access when public preview is disabled ([danielmbrasil](https://github.com/mastodon/mastodon/pull/26237))
+- Fix inefficiencies in `PlainTextFormatter` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26727))
+
+## [4.1.6] - 2023-07-31
+
+### Fixed
+
+- Fix memory leak in streaming server ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26228))
+- Fix wrong filters sometimes applying in streaming ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26159), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/26213), [renchap](https://github.com/mastodon/mastodon/pull/26233))
+- Fix incorrect connect timeout in outgoing requests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26116))
+
+## [4.1.5] - 2023-07-21
+
+### Added
+
+- Add check preventing Sidekiq workers from running with Makara configured ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25850))
+
+### Changed
+
+- Change request timeout handling to use a longer deadline ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26055))
+
+### Fixed
+
+- Fix moderation interface for remote instances with a .zip TLD ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25885))
+- Fix remote accounts being possibly persisted to database with incomplete protocol values ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25886))
+- Fix trending publishers table not rendering correctly on narrow screens ([vmstan](https://github.com/mastodon/mastodon/pull/25945))
+
+### Security
+
+- Fix CSP headers being unintentionally wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26105))
+
+## [4.1.4] - 2023-07-07
+
+### Fixed
+
+- Fix branding:generate_app_icons failing because of disallowed ICO coder ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25794))
+- Fix crash in admin interface when viewing a remote user with verified links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25796))
+- Fix processing of media files with unusual names ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25788))
+
+## [4.1.3] - 2023-07-06
+
+### Added
+
+- Add fallback redirection when getting a webfinger query `LOCAL_DOMAIN@LOCAL_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23600))
+
+### Changed
+
+- Change OpenGraph-based embeds to allow fullscreen ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25058))
+- Change AccessTokensVacuum to also delete expired tokens ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24868))
+- Change profile updates to be sent to recently-mentioned servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24852))
+- Change automatic post deletion thresholds and load detection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24614))
+- Change `/api/v1/statuses/:id/history` to always return at least one item ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25510))
+- Change auto-linking to allow carets in URL query params ([renchap](https://github.com/mastodon/mastodon/pull/25216))
+
+### Removed
+
+- Remove invalid `X-Frame-Options: ALLOWALL` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25070))
+
+### Fixed
+
+- Fix wrong view being displayed when a webhook fails validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25464))
+- Fix soft-deleted post cleanup scheduler overwhelming the streaming server ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25519))
+- Fix incorrect pagination headers in `/api/v2/admin/accounts` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25477))
+- Fix multiple inefficiencies in automatic post cleanup worker ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24607), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24785), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24840))
+- Fix performance of streaming by parsing message JSON once ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25278), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25361))
+- Fix CSP headers when `S3_ALIAS_HOST` includes a path component ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25273))
+- Fix `tootctl accounts approve --number N` not approving N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605))
+- Fix reports not being closed when performing batch suspensions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24988))
+- Fix being able to vote on your own polls ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25015))
+- Fix race condition when reblogging a status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25016))
+- Fix “Authorized applications” inefficiently and incorrectly getting last use date ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25060))
+- Fix “Authorized applications” crashing when listing apps with certain admin API scopes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25713))
+- Fix multiple N+1s in ConversationsController ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25134), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25399), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25499))
+- Fix user archive takeouts when using OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24431))
+- Fix searching for remote content by URL not working under certain conditions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25637))
+- Fix inefficiencies in indexing content for search ([VyrCossont](https://github.com/mastodon/mastodon/pull/24285), [VyrCossont](https://github.com/mastodon/mastodon/pull/24342))
+
+### Security
+
+- Add finer permission requirements for managing webhooks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25463))
+- Update dependencies
+- Add hardening headers for user-uploaded files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25756))
+- Fix verified links possibly hiding important parts of the URL (CVE-2023-36462)
+- Fix timeout handling of outbound HTTP requests (CVE-2023-36461)
+- Fix arbitrary file creation through media processing (CVE-2023-36460)
+- Fix possible XSS in preview cards (CVE-2023-36459)
+
+## [4.1.2] - 2023-04-04
+
+### Fixed
+
+- Fix crash in `tootctl` commands making use of parallelization when Elasticsearch is enabled ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24182), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24377))
+- Fix crash in `db:setup` when Elasticsearch is enabled ([rrgeorge](https://github.com/mastodon/mastodon/pull/24302))
+- Fix user archive takeout when using OpenStack Swift or S3 providers with no ACL support ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24200))
+- Fix invalid/expired invites being processed on sign-up ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24337))
+
+### Security
+
+- Update Ruby to 3.0.6 due to ReDoS vulnerabilities ([saizai](https://github.com/mastodon/mastodon/pull/24334))
+- Fix unescaped user input in LDAP query ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24379))
+
+## [4.1.1] - 2023-03-16
+
+### Added
+
+- Add redirection from paths with url-encoded `@` to their decoded form ([thijskh](https://github.com/mastodon/mastodon/pull/23593))
+- Add `lang` attribute to native language names in language picker in Web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23749))
+- Add headers to outgoing mails to avoid auto-replies ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23597))
+- Add support for refreshing many accounts at once with `tootctl accounts refresh` ([9p4](https://github.com/mastodon/mastodon/pull/23304))
+- Add confirmation modal when clicking to edit a post with a non-empty compose form ([PauloVilarinho](https://github.com/mastodon/mastodon/pull/23936))
+- Add support for the HAproxy PROXY protocol through the `PROXY_PROTO_V1` environment variable ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24064))
+- Add `SENDFILE_HEADER` environment variable ([Gargron](https://github.com/mastodon/mastodon/pull/24123))
+- Add cache headers to static files served through Rails ([Gargron](https://github.com/mastodon/mastodon/pull/24120))
+
+### Changed
+
+- Increase contrast of upload progress bar background ([toolmantim](https://github.com/mastodon/mastodon/pull/23836))
+- Change post auto-deletion throttling constants to better scale with server size ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23320))
+- Change order of bookmark and favourite sidebar entries in single-column UI for consistency ([TerryGarcia](https://github.com/mastodon/mastodon/pull/23701))
+- Change `ActivityPub::DeliveryWorker` retries to be spread out more ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21956))
+
+### Fixed
+
+- Fix “Remove all followers from the selected domains” also removing follows and notifications ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23805))
+- Fix streaming metrics format ([emilweth](https://github.com/mastodon/mastodon/pull/23519), [emilweth](https://github.com/mastodon/mastodon/pull/23520))
+- Fix case-sensitive check for previously used hashtags in hashtag autocompletion ([deanveloper](https://github.com/mastodon/mastodon/pull/23526))
+- Fix focus point of already-attached media not saving after edit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23566))
+- Fix sidebar behavior in settings/admin UI on mobile ([wxt2005](https://github.com/mastodon/mastodon/pull/23764))
+- Fix inefficiency when searching accounts per username in admin interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23801))
+- Fix duplicate “Publish” button on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23804))
+- Fix server error when failing to follow back followers from `/relationships` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23787))
+- Fix server error when attempting to display the edit history of a trendable post in the admin interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23574))
+- Fix `tootctl accounts migrate` crashing because of a typo ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23567))
+- Fix original account being unfollowed on migration before the follow request to the new account could be sent ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21957))
+- Fix the “Back” button in column headers sometimes leaving Mastodon ([c960657](https://github.com/mastodon/mastodon/pull/23953))
+- Fix pgBouncer resetting application name on every transaction ([Gargron](https://github.com/mastodon/mastodon/pull/23958))
+- Fix unconfirmed accounts being counted as active users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23803))
+- Fix `/api/v1/streaming` sub-paths not being redirected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23988))
+- Fix drag'n'drop upload area text that spans multiple lines not being centered ([vintprox](https://github.com/mastodon/mastodon/pull/24029))
+- Fix sidekiq jobs not triggering Elasticsearch index updates ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24046))
+- Fix tags being unnecessarily stripped from plain-text short site description ([c960657](https://github.com/mastodon/mastodon/pull/23975))
+- Fix HTML entities not being un-escaped in extracted plain-text from remote posts ([c960657](https://github.com/mastodon/mastodon/pull/24019))
+- Fix dashboard crash on ElasticSearch server error ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23751))
+- Fix incorrect post links in strikes when the account is remote ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23611))
+- Fix misleading error code when receiving invalid WebAuthn credentials ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23568))
+- Fix duplicate mails being sent when the SMTP server is too slow to close the connection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23750))
+
+### Security
+
+- Change user backups to use expiring URLs for download when possible ([Gargron](https://github.com/mastodon/mastodon/pull/24136))
+- Add warning for object storage misconfiguration ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24137))
+
+## [4.1.0] - 2023-02-10
+
+### Added
+
+- **Add support for importing/exporting server-wide domain blocks** ([enbylenore](https://github.com/mastodon/mastodon/pull/20597), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/21471), [dariusk](https://github.com/mastodon/mastodon/pull/22803), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/21470))
+- **Add listing of followed hashtags** ([connorshea](https://github.com/mastodon/mastodon/pull/21773))
+- **Add support for editing media description and focus point of already-sent posts** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20878))
+ - Previously, you could add and remove attachments, but not edit media description of already-attached media
+ - REST API changes:
+ - `PUT /api/v1/statuses/:id` now takes an extra `media_attributes[]` array parameter with the `id` of the updated media and their updated `description`, `focus`, and `thumbnail`
+- **Add follow request banner on account header** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20785))
+ - REST API changes:
+ - `Relationship` entities have an extra `requested_by` boolean attribute representing whether the represented user has requested to follow you
+- **Add confirmation screen when handling reports** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22375), [Gargron](https://github.com/mastodon/mastodon/pull/23156), [tribela](https://github.com/mastodon/mastodon/pull/23178))
+- Add option to make the landing page be `/about` even when trends are enabled ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20808))
+- Add `noindex` setting back to the admin interface ([prplecake](https://github.com/mastodon/mastodon/pull/22205))
+- Add instance peers API endpoint toggle back to the admin interface ([dariusk](https://github.com/mastodon/mastodon/pull/22810))
+- Add instance activity API endpoint toggle back to the admin interface ([dariusk](https://github.com/mastodon/mastodon/pull/22833))
+- Add setting for status page URL ([Gargron](https://github.com/mastodon/mastodon/pull/23390), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23499))
+ - REST API changes:
+ - Add `configuration.urls.status` attribute to the object returned by `GET /api/v2/instance`
+- Add `account.approved` webhook ([Saiv46](https://github.com/mastodon/mastodon/pull/22938))
+- Add 12 hours option to polls ([Pleclown](https://github.com/mastodon/mastodon/pull/21131))
+- Add dropdown menu item to open admin interface for remote domains ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21895))
+- Add `--remove-headers`, `--prune-profiles` and `--include-follows` flags to `tootctl media remove` ([evanphilip](https://github.com/mastodon/mastodon/pull/22149))
+- Add `--email` and `--dry-run` options to `tootctl accounts delete` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22328))
+- Add `tootctl accounts migrate` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22330))
+- Add `tootctl accounts prune` ([tribela](https://github.com/mastodon/mastodon/pull/18397))
+- Add `tootctl domains purge` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22063))
+- Add `SIDEKIQ_CONCURRENCY` environment variable ([muffinista](https://github.com/mastodon/mastodon/pull/19589))
+- Add `DB_POOL` environment variable support for streaming server ([Gargron](https://github.com/mastodon/mastodon/pull/23470))
+- Add `MIN_THREADS` environment variable to set minimum Puma threads ([jimeh](https://github.com/mastodon/mastodon/pull/21048))
+- Add explanation text to log-in page ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20946))
+- Add user profile OpenGraph tag on post pages ([bramus](https://github.com/mastodon/mastodon/pull/21423))
+- Add maskable icon support for Android ([workeffortwaste](https://github.com/mastodon/mastodon/pull/20904))
+- Add Belarusian to supported languages ([Mixaill](https://github.com/mastodon/mastodon/pull/22022))
+- Add Western Frisian to supported languages ([ykzts](https://github.com/mastodon/mastodon/pull/18602))
+- Add Montenegrin to the language picker ([ayefries](https://github.com/mastodon/mastodon/pull/21013))
+- Add Southern Sami and Lule Sami to the language picker ([Jullan-M](https://github.com/mastodon/mastodon/pull/21262))
+- Add logging for Rails cache timeouts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21667))
+- Add color highlight for active hashtag “follow” button ([MFTabriz](https://github.com/mastodon/mastodon/pull/21629))
+- Add brotli compression to `assets:precompile` ([Izorkin](https://github.com/mastodon/mastodon/pull/19025))
+- Add “disabled” account filter to the `/admin/accounts` UI ([tribela](https://github.com/mastodon/mastodon/pull/21282))
+- Add transparency to modal background for accessibility ([edent](https://github.com/mastodon/mastodon/pull/18081))
+- Add `lang` attribute to image description textarea and poll option field ([c960657](https://github.com/mastodon/mastodon/pull/23293))
+- Add `spellcheck` attribute to Content Warning and poll option input fields ([c960657](https://github.com/mastodon/mastodon/pull/23395))
+- Add `title` attribute to video elements in media attachments ([bramus](https://github.com/mastodon/mastodon/pull/21420))
+- Add left and right margins to emojis ([dsblank](https://github.com/mastodon/mastodon/pull/20464))
+- Add `roles` attribute to `Account` entities in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23255), [tribela](https://github.com/mastodon/mastodon/pull/23428))
+- Add `reading:autoplay:gifs` to `/api/v1/preferences` ([j-f1](https://github.com/mastodon/mastodon/pull/22706))
+- Add `hide_collections` parameter to `/api/v1/accounts/credentials` ([CarlSchwan](https://github.com/mastodon/mastodon/pull/22790))
+- Add `policy` attribute to web push subscription objects in REST API at `/api/v1/push/subscriptions` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23210))
+- Add metrics endpoint to streaming API ([Gargron](https://github.com/mastodon/mastodon/pull/23388), [Gargron](https://github.com/mastodon/mastodon/pull/23469))
+- Add more specific error messages to HTTP signature verification ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21617))
+- Add Storj DCS to cloud object storage options in the `mastodon:setup` rake task ([jtolio](https://github.com/mastodon/mastodon/pull/21929))
+- Add checkmark symbol in the checkbox for sensitive media ([sidp](https://github.com/mastodon/mastodon/pull/22795))
+- Add missing accessibility attributes to logout link in modals ([kytta](https://github.com/mastodon/mastodon/pull/22549))
+- Add missing accessibility attributes to “Hide image” button in `MediaGallery` ([hs4man21](https://github.com/mastodon/mastodon/pull/22513))
+- Add missing accessibility attributes to hide content warning field when disabled ([hs4man21](https://github.com/mastodon/mastodon/pull/22568))
+- Add `aria-hidden` to footer circle dividers to improve accessibility ([hs4man21](https://github.com/mastodon/mastodon/pull/22576))
+- Add `lang` attribute to compose form inputs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23240))
+
+### Changed
+
+- **Ensure exact match is the first result in hashtag searches** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21315))
+- Change account search to return followed accounts first ([dariusk](https://github.com/mastodon/mastodon/pull/22956))
+- Change batch account suspension to create a strike ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20897))
+- Change default reply language to match the default language when replying to a translated post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22272))
+- Change misleading wording about waitlists ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20850))
+- Increase width of the unread notification border ([connorshea](https://github.com/mastodon/mastodon/pull/21692))
+- Change new post notification button on profiles to make it more apparent when it is enabled ([tribela](https://github.com/mastodon/mastodon/pull/22541))
+- Change trending tags admin interface to always show batch action controls ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23013))
+- Change wording of some OAuth scope descriptions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22491))
+- Change wording of admin report handling actions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18388))
+- Change confirm prompts for relationships management ([tribela](https://github.com/mastodon/mastodon/pull/19411))
+- Change language surrounding disability in prompts for media descriptions ([hs4man21](https://github.com/mastodon/mastodon/pull/20923))
+- Change confusing wording in the sign in banner ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22490))
+- Change `POST /settings/applications/:id` to regenerate token on scopes change ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23359))
+- Change account moderation notes to make links clickable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22553))
+- Change link previews for statuses to never use avatar as fallback ([Gargron](https://github.com/mastodon/mastodon/pull/23376))
+- Change email address input to be read-only for logged-in users when requesting a new confirmation e-mail ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23247))
+- Change notifications per page from 15 to 40 in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/23348))
+- Change number of stored items in home feed from 400 to 800 ([Gargron](https://github.com/mastodon/mastodon/pull/23349))
+- Change API rate limits from 300/5min per user to 1500/5min per user, 300/5min per app ([Gargron](https://github.com/mastodon/mastodon/pull/23347))
+- Save avatar or header correctly even if the other one fails ([tribela](https://github.com/mastodon/mastodon/pull/18465))
+- Change `referrer-policy` to `same-origin` application-wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23037))
+- Add 'private' to `Cache-Control`, match Rails expectations ([daxtens](https://github.com/mastodon/mastodon/pull/20608))
+- Make the button that expands the compose form differentiable from the button that publishes a post ([Tak](https://github.com/mastodon/mastodon/pull/20864))
+- Change automatic post deletion configuration to be accessible to moved users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20774))
+- Make tag following idempotent ([trwnh](https://github.com/mastodon/mastodon/pull/20860), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/21285))
+- Use buildx functions for faster builds ([inductor](https://github.com/mastodon/mastodon/pull/20692))
+- Split off Dockerfile components for faster builds ([moritzheiber](https://github.com/mastodon/mastodon/pull/20933), [ineffyble](https://github.com/mastodon/mastodon/pull/20948), [BtbN](https://github.com/mastodon/mastodon/pull/21028))
+- Change last occurrence of “silence” to “limit” in UI text ([cincodenada](https://github.com/mastodon/mastodon/pull/20637))
+- Change “hide toot” to “hide post” ([seanthegeek](https://github.com/mastodon/mastodon/pull/22385))
+- Don't allow URLs that contain non-normalized paths to be verified ([dgl](https://github.com/mastodon/mastodon/pull/20999))
+- Change the “Trending now” header to be a link to the Explore page ([connorshea](https://github.com/mastodon/mastodon/pull/21759))
+- Change PostgreSQL connection timeout from 2 minutes to 15 seconds ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21790))
+- Make handle more easily selectable on profile page ([cadars](https://github.com/mastodon/mastodon/pull/21479))
+- Allow admins to refresh remotely-suspended accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22327))
+- Change dropdown menu to contain “Copy link to post” even for non-public posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21316))
+- Allow adding relays in secure mode and limited federation mode ([ineffyble](https://github.com/mastodon/mastodon/pull/22324))
+- Change timestamps to be displayed using the user's timezone throughout the moderation interface ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/21878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22555))
+- Change CSP directives on API to be tight and concise ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20960))
+- Change web UI to not autofocus the compose form ([raboof](https://github.com/mastodon/mastodon/pull/16517), [Akkiesoft](https://github.com/mastodon/mastodon/pull/23094))
+- Change idempotency key handling for posting when database access is slow ([lambda](https://github.com/mastodon/mastodon/pull/21840))
+- Change remote media files to be downloaded outside of transactions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21796))
+- Improve contrast of charts in “poll has ended” notifications ([j-f1](https://github.com/mastodon/mastodon/pull/22575))
+- Change OEmbed detection and validation to be somewhat more lenient ([ineffyble](https://github.com/mastodon/mastodon/pull/22533))
+- Widen ElasticSearch version detection to not display a warning for OpenSearch ([VyrCossont](https://github.com/mastodon/mastodon/pull/22422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23064))
+- Change link verification to allow pages larger than 1MB as long as the link is in the first 1MB ([untitaker](https://github.com/mastodon/mastodon/pull/22879))
+- Update default Node.js version to Node.js 16 ([ineffyble](https://github.com/mastodon/mastodon/pull/22223), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22342))
+
+### Removed
+
+- Officially remove support for Ruby 2.6 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21477))
+- Remove `object-fit` polyfill used for old versions of Microsoft Edge ([shuuji3](https://github.com/mastodon/mastodon/pull/22693))
+- Remove `intersection-observer` polyfill for old Safari support ([shuuji3](https://github.com/mastodon/mastodon/pull/23284))
+- Remove empty `title` tag from mailer layout ([nametoolong](https://github.com/mastodon/mastodon/pull/23078))
+- Remove post count and last posts from ActivityPub representation of hashtag collections ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23460))
+
+### Fixed
+
+- **Fix changing domain block severity not undoing individual account effects** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22135))
+- Fix suspension worker crashing on S3-compatible setups without ACL support ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22487))
+- Fix possible race conditions when suspending/unsuspending accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22363))
+- Fix being stuck in edit mode when deleting the edited posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22126))
+- Fix attached media uploads not being cleared when replying to a post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23504))
+- Fix filters not being applied to some notification types ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23211))
+- Fix incorrect link in push notifications for some event types ([elizabeth-dev](https://github.com/mastodon/mastodon/pull/23286))
+- Fix some performance issues with `/admin/instances` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21907))
+- Fix some pre-4.0 admin audit logs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22091))
+- Fix moderation audit log items for warnings having incorrect links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23242))
+- Fix account activation being sometimes triggered before email confirmation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23245))
+- Fix missing OAuth scopes for admin APIs ([trwnh](https://github.com/mastodon/mastodon/pull/20918), [trwnh](https://github.com/mastodon/mastodon/pull/20979))
+- Fix voter count not being cleared when a poll is reset ([afontenot](https://github.com/mastodon/mastodon/pull/21700))
+- Fix attachments of edited posts not being fetched ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21565))
+- Fix irreversible and whole_word parameters handling in `/api/v1/filters` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21988))
+- Fix 500 error when marking posts as sensitive while some of them are deleted ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22134))
+- Fix expanded posts not always being scrolled into view ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21797))
+- Fix not being able to scroll the remote interaction modal on small screens ([xendke](https://github.com/mastodon/mastodon/pull/21763))
+- Fix not being able to scroll in post history modal ([cadars](https://github.com/mastodon/mastodon/pull/23396))
+- Fix audio player volume control on Safari ([minacle](https://github.com/mastodon/mastodon/pull/23187))
+- Fix disappearing “Explore” tabs on Safari ([nyura](https://github.com/mastodon/mastodon/pull/20917), [ykzts](https://github.com/mastodon/mastodon/pull/20982))
+- Fix wrong padding in RTL layout ([Gargron](https://github.com/mastodon/mastodon/pull/23157))
+- Fix drag & drop upload area display in single-column mode ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23217))
+- Fix being unable to get a single EmailDomainBlock from the admin API ([trwnh](https://github.com/mastodon/mastodon/pull/20846))
+- Fix admin-set follow recommandations being case-sensitive ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23500))
+- Fix unserialized `role` on account entities in admin API ([Gargron](https://github.com/mastodon/mastodon/pull/23290))
+- Fix pagination of followed tags ([trwnh](https://github.com/mastodon/mastodon/pull/20861))
+- Fix dropdown menu positions when scrolling ([sidp](https://github.com/mastodon/mastodon/pull/22916), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23062))
+- Fix email with empty domain name labels passing validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23246))
+- Fix mysterious registration failure when “Require a reason to join” is set with open registrations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22127))
+- Fix attachment rendering of edited posts in OpenGraph ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22270))
+- Fix invalid/empty RSS feed link on account pages ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20772))
+- Fix error in `VerifyLinkService` when processing links with no href ([joshuap](https://github.com/mastodon/mastodon/pull/20741))
+- Fix error in `VerifyLinkService` when processing links with invalid URLs ([untitaker](https://github.com/mastodon/mastodon/pull/23204))
+- Fix media uploads with FFmpeg 5 ([dead10ck](https://github.com/mastodon/mastodon/pull/21191))
+- Fix sensitive flag not being set when replying to a post with a content warning under certain conditions ([kedamaDQ](https://github.com/mastodon/mastodon/pull/21724))
+- Fix misleading message briefly showing up when loading follow requests under some conditions ([c960657](https://github.com/mastodon/mastodon/pull/23386))
+- Fix “Share @:user's profile” profile menu item not working ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21490))
+- Fix crash and incorrect behavior in `tootctl domains crawl` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19004))
+- Fix autoplay on iOS ([jamesadney](https://github.com/mastodon/mastodon/pull/21422))
+- Fix user clean-up scheduler crash when an unconfirmed account has a moderation note ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23318))
+- Fix spaces not being stripped in admin account search ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21324))
+- Fix spaces not being stripped when adding relays ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22655))
+- Fix infinite loading spinner instead of soft 404 for non-existing remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21303))
+- Fix minor visual issue with the top border of verified account fields ([j-f1](https://github.com/mastodon/mastodon/pull/22006))
+- Fix pending account approval and rejection not being recorded in the admin audit log ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/22088))
+- Fix “Sign up” button with closed registrations not opening modal on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22060))
+- Fix UI header overflowing on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21783))
+- Fix 500 error when trying to migrate to an invalid address ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21462))
+- Fix crash when trying to fetch unobtainable avatar of user using external authentication ([lochiiconnectivity](https://github.com/mastodon/mastodon/pull/22462))
+- Fix processing error on incoming malformed JSON-LD under some situations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23416))
+- Fix potential duplicate posts in Explore tab ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22121))
+- Fix deprecation warning in `tootctl accounts rotate` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22120))
+- Fix styling of featured tags in light theme ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23252))
+- Fix missing style in warning and strike cards ([AtelierSnek](https://github.com/mastodon/mastodon/pull/22177), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22302))
+- Fix wasteful request to `/api/v1/custom_emojis` when not logged in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22326))
+- Fix replies sometimes being delivered to user-blocked domains ([tribela](https://github.com/mastodon/mastodon/pull/22117))
+- Fix admin dashboard crash when using some ElasticSearch replacements ([cortices](https://github.com/mastodon/mastodon/pull/21006))
+- Fix profile avatar being slightly offset into left border ([RiedleroD](https://github.com/mastodon/mastodon/pull/20994))
+- Fix N+1 queries in `NotificationsController` ([nametoolong](https://github.com/mastodon/mastodon/pull/21202))
+- Fix being unable to react to announcements with the keycap number sign emoji ([kescherCode](https://github.com/mastodon/mastodon/pull/22231))
+- Fix height computation of post embeds ([hodgesmr](https://github.com/mastodon/mastodon/pull/22141))
+- Fix accessibility issue of the search bar due to hidden placeholder ([alexstine](https://github.com/mastodon/mastodon/pull/21275))
+- Fix layout change handler not being removed due to a typo ([nschonni](https://github.com/mastodon/mastodon/pull/21829))
+- Fix typo in the default `S3_HOSTNAME` used in the `mastodon:setup` rake task ([danp](https://github.com/mastodon/mastodon/pull/19932))
+- Fix the top action bar appearing in the multi-column layout ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20943))
+- Fix inability to use local LibreTranslate without setting `ALLOWED_PRIVATE_ADDRESSES` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21926))
+- Fix punycoded local domains not being prettified in initial state ([Tritlo](https://github.com/mastodon/mastodon/pull/21440))
+- Fix CSP violation warning by removing inline CSS from SVG logo ([luxiaba](https://github.com/mastodon/mastodon/pull/20814))
+- Fix margin for search field on medium window size ([minacle](https://github.com/mastodon/mastodon/pull/21606))
+- Fix search popout scrolling with the page in single-column mode ([rgroothuijsen](https://github.com/mastodon/mastodon/pull/16463))
+- Fix minor post cache hydration discrepancy ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19879))
+- Fix `・` detection in hashtags ([parthoghosh24](https://github.com/mastodon/mastodon/pull/22888))
+- Fix hashtag follows bypassing user blocks ([tribela](https://github.com/mastodon/mastodon/pull/22849))
+- Fix moved accounts being incorrectly redirected to account settings when trying to view a remote profile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22497))
+- Fix site upload validations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22479))
+- Fix “Add new domain block” button using last submitted search value instead of the current one ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22485))
+- Fix misleading hashtag warning when posting with “Followers only” or “Mentioned people only” visibility ([n0toose](https://github.com/mastodon/mastodon/pull/22827))
+- Fix embedded posts with videos grabbing focus ([Akkiesoft](https://github.com/mastodon/mastodon/pull/22778))
+- Fix `$` not being escaped in `.env.production` files generated by the `mastodon:setup` rake task ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23012), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23072))
+- Fix sanitizer parsing link text as HTML when stripping unsupported links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22558))
+- Fix `scheduled_at` input not using `datetime-local` when editing announcements ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21896))
+- Fix REST API serializer for `Account` not including `moved` when the moved account has itself moved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22483))
+- Fix `/api/v1/admin/trends/tags` using wrong serializer ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18943))
+- Fix situations in which instance actor can be set to a Mastodon-incompatible name ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22307))
+
+### Security
+
+- Add `form-action` CSP directive ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20781), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20958), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20962))
+- Fix unbounded recursion in account discovery ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22025))
+- Revoke all authorized applications on password reset ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/21325))
+- Fix unbounded recursion in post discovery ([ClearlyClaire,nametoolong](https://github.com/mastodon/mastodon/pull/23506))
+
+## [4.0.2] - 2022-11-15
+
+### Fixed
+
+- Fix wrong color on mentions hidden behind content warning in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20724))
+- Fix filters from other users being used in the streaming service ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20719))
+- Fix `unsafe-eval` being used when `wasm-unsafe-eval` is enough in Content Security Policy ([Gargron](https://github.com/mastodon/mastodon/pull/20729), [prplecake](https://github.com/mastodon/mastodon/pull/20606))
+
+## [4.0.1] - 2022-11-14
+
+### Fixed
+
+- Fix nodes order being sometimes mangled when rewriting emoji ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20677))
+
+## [4.0.0] - 2022-11-14
+
+Some of the features in this release have been funded through the [NGI0 Discovery](https://nlnet.nl/discovery) Fund, a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825322.
+
+### Added
+
+- Add ability to filter followed accounts' posts by language ([Gargron](https://github.com/mastodon/mastodon/pull/19095), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19268))
+- **Add ability to follow hashtags** ([Gargron](https://github.com/mastodon/mastodon/pull/18809), [Gargron](https://github.com/mastodon/mastodon/pull/18862), [Gargron](https://github.com/mastodon/mastodon/pull/19472), [noellabo](https://github.com/mastodon/mastodon/pull/18924))
+- Add ability to filter individual posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18945))
+- **Add ability to translate posts** ([Gargron](https://github.com/mastodon/mastodon/pull/19218), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19433), [Gargron](https://github.com/mastodon/mastodon/pull/19453), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19434), [Gargron](https://github.com/mastodon/mastodon/pull/19388), [ykzts](https://github.com/mastodon/mastodon/pull/19244), [Gargron](https://github.com/mastodon/mastodon/pull/19245))
+- Add featured tags to web UI ([noellabo](https://github.com/mastodon/mastodon/pull/19408), [noellabo](https://github.com/mastodon/mastodon/pull/19380), [noellabo](https://github.com/mastodon/mastodon/pull/19358), [noellabo](https://github.com/mastodon/mastodon/pull/19409), [Gargron](https://github.com/mastodon/mastodon/pull/19382), [ykzts](https://github.com/mastodon/mastodon/pull/19418), [noellabo](https://github.com/mastodon/mastodon/pull/19403), [noellabo](https://github.com/mastodon/mastodon/pull/19404), [Gargron](https://github.com/mastodon/mastodon/pull/19398), [Gargron](https://github.com/mastodon/mastodon/pull/19712), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20018))
+- **Add support for language preferences for trending statuses and links** ([Gargron](https://github.com/mastodon/mastodon/pull/18288), [Gargron](https://github.com/mastodon/mastodon/pull/19349), [ykzts](https://github.com/mastodon/mastodon/pull/19335))
+ - Previously, you could only see trends in your current language
+ - For less popular languages, that meant empty trends
+ - Now, trends in your preferred languages' are shown on top, with others beneath
+- Add server rules to sign-up flow ([Gargron](https://github.com/mastodon/mastodon/pull/19296))
+- Add privacy icons to report modal in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19190))
+- Add `noopener` to links to remote profiles in web UI ([shleeable](https://github.com/mastodon/mastodon/pull/19014))
+- Add option to open original page in dropdowns of remote content in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20299))
+- Add warning for sensitive audio posts in web UI ([rgroothuijsen](https://github.com/mastodon/mastodon/pull/17885))
+- Add language attribute to posts in web UI ([tribela](https://github.com/mastodon/mastodon/pull/18544))
+- Add support for uploading WebP files ([Saiv46](https://github.com/mastodon/mastodon/pull/18506))
+- Add support for uploading `audio/vnd.wave` files ([tribela](https://github.com/mastodon/mastodon/pull/18737))
+- Add support for uploading AVIF files ([txt-file](https://github.com/mastodon/mastodon/pull/19647))
+- Add support for uploading HEIC files ([Gargron](https://github.com/mastodon/mastodon/pull/19618))
+- Add more debug information when processing remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/15605), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19209))
+- **Add retention policy for cached content and media** ([Gargron](https://github.com/mastodon/mastodon/pull/19232), [zunda](https://github.com/mastodon/mastodon/pull/19478), [Gargron](https://github.com/mastodon/mastodon/pull/19458), [Gargron](https://github.com/mastodon/mastodon/pull/19248))
+ - Set for how long remote posts or media should be cached on your server
+ - Hands-off alternative to `tootctl` commands
+- **Add customizable user roles** ([Gargron](https://github.com/mastodon/mastodon/pull/18641), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18812), [Gargron](https://github.com/mastodon/mastodon/pull/19040), [tribela](https://github.com/mastodon/mastodon/pull/18825), [tribela](https://github.com/mastodon/mastodon/pull/18826), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18776), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18777), [unextro](https://github.com/mastodon/mastodon/pull/18786), [tribela](https://github.com/mastodon/mastodon/pull/18824), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19436))
+ - Previously, there were 3 hard-coded roles, user, moderator, and admin
+ - Create your own roles and decide which permissions they should have
+- Add notifications for new reports ([Gargron](https://github.com/mastodon/mastodon/pull/18697), [Gargron](https://github.com/mastodon/mastodon/pull/19475))
+- Add ability to select all accounts matching search for batch actions in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19053), [Gargron](https://github.com/mastodon/mastodon/pull/19054))
+- Add ability to view previous edits of a status in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19462))
+- Add ability to block sign-ups from IP ([Gargron](https://github.com/mastodon/mastodon/pull/19037))
+- **Add webhooks to admin UI** ([Gargron](https://github.com/mastodon/mastodon/pull/18510))
+- Add admin API for managing domain allows ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18668))
+- Add admin API for managing domain blocks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18247))
+- Add admin API for managing e-mail domain blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19066))
+- Add admin API for managing canonical e-mail blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19067))
+- Add admin API for managing IP blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19065), [trwnh](https://github.com/mastodon/mastodon/pull/20207))
+- Add `sensitized` attribute to accounts in admin REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20094))
+- Add `services` and `metadata` to the NodeInfo endpoint ([MFTabriz](https://github.com/mastodon/mastodon/pull/18563))
+- Add `--remove-role` option to `tootctl accounts modify` ([Gargron](https://github.com/mastodon/mastodon/pull/19477))
+- Add `--days` option to `tootctl media refresh` ([tribela](https://github.com/mastodon/mastodon/pull/18425))
+- Add `EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION` environment variable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18642))
+- Add `IP_RETENTION_PERIOD` and `SESSION_RETENTION_PERIOD` environment variables ([kescherCode](https://github.com/mastodon/mastodon/pull/18757))
+- Add `http_hidden_proxy` environment variable ([tribela](https://github.com/mastodon/mastodon/pull/18427))
+- Add `ENABLE_STARTTLS` environment variable ([erbridge](https://github.com/mastodon/mastodon/pull/20321))
+- Add caching for payload serialization during fan-out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19637), [Gargron](https://github.com/mastodon/mastodon/pull/19642), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19746), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19747), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19963))
+- Add assets from Twemoji 14.0 ([Gargron](https://github.com/mastodon/mastodon/pull/19733))
+- Add reputation and followers score boost to SQL-only account search ([Gargron](https://github.com/mastodon/mastodon/pull/19251))
+- Add Scots, Balaibalan, Láadan, Lingua Franca Nova, Lojban, Toki Pona to languages list ([VyrCossont](https://github.com/mastodon/mastodon/pull/20168))
+- Set autocomplete hints for e-mail, password and OTP fields ([rcombs](https://github.com/mastodon/mastodon/pull/19833), [offbyone](https://github.com/mastodon/mastodon/pull/19946), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20071))
+- Add support for DigitalOcean Spaces in setup wizard ([v-aisac](https://github.com/mastodon/mastodon/pull/20573))
+
+### Changed
+
+- **Change brand color and logotypes** ([Gargron](https://github.com/mastodon/mastodon/pull/18592), [Gargron](https://github.com/mastodon/mastodon/pull/18639), [Gargron](https://github.com/mastodon/mastodon/pull/18691), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18634), [Gargron](https://github.com/mastodon/mastodon/pull/19254), [mayaeh](https://github.com/mastodon/mastodon/pull/18710))
+- **Change post editing to be enabled in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/19103))
+- **Change web UI to work for logged-out users** ([Gargron](https://github.com/mastodon/mastodon/pull/18961), [Gargron](https://github.com/mastodon/mastodon/pull/19250), [Gargron](https://github.com/mastodon/mastodon/pull/19294), [Gargron](https://github.com/mastodon/mastodon/pull/19306), [Gargron](https://github.com/mastodon/mastodon/pull/19315), [ykzts](https://github.com/mastodon/mastodon/pull/19322), [Gargron](https://github.com/mastodon/mastodon/pull/19412), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19437), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19415), [Gargron](https://github.com/mastodon/mastodon/pull/19348), [Gargron](https://github.com/mastodon/mastodon/pull/19295), [Gargron](https://github.com/mastodon/mastodon/pull/19422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19414), [Gargron](https://github.com/mastodon/mastodon/pull/19319), [Gargron](https://github.com/mastodon/mastodon/pull/19345), [Gargron](https://github.com/mastodon/mastodon/pull/19310), [Gargron](https://github.com/mastodon/mastodon/pull/19301), [Gargron](https://github.com/mastodon/mastodon/pull/19423), [ykzts](https://github.com/mastodon/mastodon/pull/19471), [ykzts](https://github.com/mastodon/mastodon/pull/19333), [ykzts](https://github.com/mastodon/mastodon/pull/19337), [ykzts](https://github.com/mastodon/mastodon/pull/19272), [ykzts](https://github.com/mastodon/mastodon/pull/19468), [Gargron](https://github.com/mastodon/mastodon/pull/19466), [Gargron](https://github.com/mastodon/mastodon/pull/19457), [Gargron](https://github.com/mastodon/mastodon/pull/19426), [Gargron](https://github.com/mastodon/mastodon/pull/19427), [Gargron](https://github.com/mastodon/mastodon/pull/19421), [Gargron](https://github.com/mastodon/mastodon/pull/19417), [Gargron](https://github.com/mastodon/mastodon/pull/19413), [Gargron](https://github.com/mastodon/mastodon/pull/19397), [Gargron](https://github.com/mastodon/mastodon/pull/19387), [Gargron](https://github.com/mastodon/mastodon/pull/19396), [Gargron](https://github.com/mastodon/mastodon/pull/19385), [ykzts](https://github.com/mastodon/mastodon/pull/19334), [ykzts](https://github.com/mastodon/mastodon/pull/19329), [Gargron](https://github.com/mastodon/mastodon/pull/19324), [Gargron](https://github.com/mastodon/mastodon/pull/19318), [Gargron](https://github.com/mastodon/mastodon/pull/19316), [Gargron](https://github.com/mastodon/mastodon/pull/19263), [trwnh](https://github.com/mastodon/mastodon/pull/19305), [ykzts](https://github.com/mastodon/mastodon/pull/19273), [Gargron](https://github.com/mastodon/mastodon/pull/19801), [Gargron](https://github.com/mastodon/mastodon/pull/19790), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19773), [Gargron](https://github.com/mastodon/mastodon/pull/19798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19724), [Gargron](https://github.com/mastodon/mastodon/pull/19709), [Gargron](https://github.com/mastodon/mastodon/pull/19514), [Gargron](https://github.com/mastodon/mastodon/pull/19562), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19981), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19978), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20148), [Gargron](https://github.com/mastodon/mastodon/pull/20302), [cutls](https://github.com/mastodon/mastodon/pull/20400))
+ - The web app can now be accessed without being logged in
+ - No more `/web` prefix on web app paths
+ - Profiles, posts, and other public pages now use the same interface for logged in and logged out users
+ - The web app displays a server information banner
+ - Pop-up windows for remote interaction have been replaced with a modal window
+ - No need to type in your username for remote interaction, copy-paste-to-search method explained
+ - Various hints throughout the app explain what the different timelines are
+ - New about page design
+ - New privacy policy page design shows when the policy was last updated
+ - All sections of the web app now have appropriate window titles
+ - The layout of the interface has been streamlined between different screen sizes
+ - Posts now use more horizontal space
+- Change label of publish button to be "Publish" again in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/18583))
+- Change language to be carried over on reply in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18557))
+- Change "Unfollow" to "Cancel follow request" when request still pending in web UI ([prplecake](https://github.com/mastodon/mastodon/pull/19363))
+- **Change post filtering system** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18058), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19050), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18894), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19051), [noellabo](https://github.com/mastodon/mastodon/pull/18923), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18744), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20567))
+ - Filtered keywords and phrases can now be grouped into named categories
+ - Filtered posts show which exact filter was hit
+ - Individual posts can be added to a filter
+ - You can peek inside filtered posts anyway
+- Change path of privacy policy page from `/terms` to `/privacy-policy` ([Gargron](https://github.com/mastodon/mastodon/pull/19249))
+- Change how hashtags are normalized ([Gargron](https://github.com/mastodon/mastodon/pull/18795), [Gargron](https://github.com/mastodon/mastodon/pull/18863), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18854))
+- Change settings area to be separated into categories in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19407), [Gargron](https://github.com/mastodon/mastodon/pull/19533))
+- Change "No accounts selected" errors to use the appropriate noun in admin UI ([prplecake](https://github.com/mastodon/mastodon/pull/19356))
+- Change e-mail domain blocks to match subdomains of blocked domains ([Gargron](https://github.com/mastodon/mastodon/pull/18979))
+- Change custom emoji file size limit from 50 KB to 256 KB ([Gargron](https://github.com/mastodon/mastodon/pull/18788))
+- Change "Allow trends without prior review" setting to also work for trending posts ([Gargron](https://github.com/mastodon/mastodon/pull/17977))
+- Change admin announcements form to use single inputs for date and time in admin UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18321))
+- Change search API to be accessible without being logged in ([Gargron](https://github.com/mastodon/mastodon/pull/18963), [Gargron](https://github.com/mastodon/mastodon/pull/19326))
+- Change following and followers API to be accessible without being logged in ([Gargron](https://github.com/mastodon/mastodon/pull/18964))
+- Change `AUTHORIZED_FETCH` to not block unauthenticated REST API access ([Gargron](https://github.com/mastodon/mastodon/pull/19803))
+- Change Helm configuration ([deepy](https://github.com/mastodon/mastodon/pull/18997), [jgsmith](https://github.com/mastodon/mastodon/pull/18415), [deepy](https://github.com/mastodon/mastodon/pull/18941))
+- Change mentions of blocked users to not be processed ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19725))
+- Change max. thumbnail dimensions to 640x360px (360p) ([Gargron](https://github.com/mastodon/mastodon/pull/19619))
+- Change post-processing to be deferred only for large media types ([Gargron](https://github.com/mastodon/mastodon/pull/19617))
+- Change link verification to only work for https links without unicode ([Gargron](https://github.com/mastodon/mastodon/pull/20304), [Gargron](https://github.com/mastodon/mastodon/pull/20295))
+- Change account deletion requests to spread out over time ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20222))
+- Change larger reblogs/favourites numbers to be shortened in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20303))
+- Change incoming activity processing to happen in `ingress` queue ([Gargron](https://github.com/mastodon/mastodon/pull/20264))
+- Change notifications to not link show preview cards in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20335))
+- Change amount of replies returned for logged out users in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20355))
+- Change in-app links to keep you in-app in web UI ([trwnh](https://github.com/mastodon/mastodon/pull/20540), [Gargron](https://github.com/mastodon/mastodon/pull/20628))
+- Change table header to be sticky in admin UI ([sk22](https://github.com/mastodon/mastodon/pull/20442))
+
+### Removed
+
+- Remove setting that disables account deletes ([Gargron](https://github.com/mastodon/mastodon/pull/17683))
+- Remove digest e-mails ([Gargron](https://github.com/mastodon/mastodon/pull/17985))
+- Remove unnecessary sections from welcome e-mail ([Gargron](https://github.com/mastodon/mastodon/pull/19299))
+- Remove item titles from RSS feeds ([Gargron](https://github.com/mastodon/mastodon/pull/18640))
+- Remove volume number from hashtags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19253))
+- Remove Nanobox configuration ([tonyjiang](https://github.com/mastodon/mastodon/pull/17881))
+
+### Fixed
+
+- Fix rules with same priority being sorted non-deterministically ([Gargron](https://github.com/mastodon/mastodon/pull/20623))
+- Fix error when invalid domain name is submitted ([Gargron](https://github.com/mastodon/mastodon/pull/19474))
+- Fix icons having an image role ([Gargron](https://github.com/mastodon/mastodon/pull/20600))
+- Fix connections to IPv6-only servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20108))
+- Fix unnecessary service worker registration and preloading when logged out in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20341))
+- Fix unnecessary and slow regex construction ([raggi](https://github.com/mastodon/mastodon/pull/20215))
+- Fix `mailers` queue not being used for mailers ([Gargron](https://github.com/mastodon/mastodon/pull/20274))
+- Fix error in webfinger redirect handling ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20260))
+- Fix report category not being set to `violation` if rule IDs are provided ([trwnh](https://github.com/mastodon/mastodon/pull/20137))
+- Fix nodeinfo metadata attribute being an array instead of an object ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20114))
+- Fix account endorsements not being idempotent ([trwnh](https://github.com/mastodon/mastodon/pull/20118))
+- Fix status and rule IDs not being strings in admin reports REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20122))
+- Fix error on invalid `replies_policy` in REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20126))
+- Fix redrafting a currently-editing post not leaving edit mode in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20023))
+- Fix performance by avoiding method cache busts ([raggi](https://github.com/mastodon/mastodon/pull/19957))
+- Fix opening the language picker scrolling the single-column view to the top in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19983))
+- Fix content warning button missing `aria-expanded` attribute in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19975))
+- Fix redundant `aria-pressed` attributes in web UI ([Brawaru](https://github.com/mastodon/mastodon/pull/19912))
+- Fix crash when external auth provider has no display name set ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19962))
+- Fix followers count not being updated when migrating follows ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19998))
+- Fix double button to clear emoji search input in web UI ([sunny](https://github.com/mastodon/mastodon/pull/19888))
+- Fix missing null check on applications on strike disputes ([kescherCode](https://github.com/mastodon/mastodon/pull/19851))
+- Fix featured tags not saving preferred casing ([Gargron](https://github.com/mastodon/mastodon/pull/19732))
+- Fix language not being saved when editing status ([Gargron](https://github.com/mastodon/mastodon/pull/19543))
+- Fix not being able to input featured tag with hash symbol ([Gargron](https://github.com/mastodon/mastodon/pull/19535))
+- Fix user clean-up scheduler crash when an unconfirmed account has a moderation note ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19629))
+- Fix being unable to withdraw follow request when confirmation modal is disabled in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19687))
+- Fix inaccurate admin log entry for re-sending confirmation e-mails ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19674))
+- Fix edits not being immediately reflected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19673))
+- Fix bookmark import stopping at the first failure ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19669))
+- Fix account action type validation ([Gargron](https://github.com/mastodon/mastodon/pull/19476))
+- Fix upload progress not communicating processing phase in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19530))
+- Fix wrong host being used for custom.css when asset host configured ([Gargron](https://github.com/mastodon/mastodon/pull/19521))
+- Fix account migration form ever using outdated account data ([Gargron](https://github.com/mastodon/mastodon/pull/18429), [nightpool](https://github.com/mastodon/mastodon/pull/19883))
+- Fix error when uploading malformed CSV import ([Gargron](https://github.com/mastodon/mastodon/pull/19509))
+- Fix avatars not using image tags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19488))
+- Fix handling of duplicate and out-of-order notifications in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19693))
+- Fix reblogs being discarded after the reblogged status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19731))
+- Fix indexing scheduler trying to index when Elasticsearch is disabled ([Gargron](https://github.com/mastodon/mastodon/pull/19805))
+- Fix n+1 queries when rendering initial state JSON ([Gargron](https://github.com/mastodon/mastodon/pull/19795))
+- Fix n+1 query during status removal ([Gargron](https://github.com/mastodon/mastodon/pull/19753))
+- Fix OCR not working due to Content Security Policy in web UI ([prplecake](https://github.com/mastodon/mastodon/pull/18817))
+- Fix `nofollow` rel being removed in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19455))
+- Fix language dropdown causing zoom on mobile devices in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19428))
+- Fix button to dismiss suggestions not showing up in search results in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19325))
+- Fix language dropdown sometimes not appearing in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19246))
+- Fix quickly switching notification filters resulting in empty or incorrect list in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19052), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18960))
+- Fix media modal link button in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18877))
+- Fix error upon successful account migration ([Gargron](https://github.com/mastodon/mastodon/pull/19386))
+- Fix negatives values in search index causing queries to fail ([Gargron](https://github.com/mastodon/mastodon/pull/19464), [Gargron](https://github.com/mastodon/mastodon/pull/19481))
+- Fix error when searching for invalid URL ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18580))
+- Fix IP blocks not having a unique index ([Gargron](https://github.com/mastodon/mastodon/pull/19456))
+- Fix remote account in contact account setting not being used ([Gargron](https://github.com/mastodon/mastodon/pull/19351))
+- Fix swallowing mentions of unconfirmed/unapproved users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19191))
+- Fix incorrect and slow cache invalidation when blocking domain and removing media attachments ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19062))
+- Fix HTTPs redirect behaviour when running as I2P service ([gi-yt](https://github.com/mastodon/mastodon/pull/18929))
+- Fix deleted pinned posts potentially counting towards the pinned posts limit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19005))
+- Fix compatibility with OpenSSL 3.0 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18449))
+- Fix error when a remote report includes a private post the server has no access to ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18760))
+- Fix suspicious sign-in mails never being sent ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18599))
+- Fix fallback locale when somehow user's locale is an empty string ([tribela](https://github.com/mastodon/mastodon/pull/18543))
+- Fix avatar/header not being deleted locally when deleted on remote account ([tribela](https://github.com/mastodon/mastodon/pull/18973))
+- Fix missing `,` in Blurhash validation ([noellabo](https://github.com/mastodon/mastodon/pull/18660))
+- Fix order by most recent not working for relationships page in admin UI ([tribela](https://github.com/mastodon/mastodon/pull/18996))
+- Fix uncaught error when invalid date is supplied to API ([Gargron](https://github.com/mastodon/mastodon/pull/19480))
+- Fix REST API sometimes returning HTML on error ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19135))
+- Fix ambiguous column names in `tootctl media refresh` ([tribela](https://github.com/mastodon/mastodon/pull/19206))
+- Fix ambiguous column names in `tootctl search deploy` ([mashirozx](https://github.com/mastodon/mastodon/pull/18993))
+- Fix `CDN_HOST` not being used in some asset URLs ([tribela](https://github.com/mastodon/mastodon/pull/18662))
+- Fix `CAS_DISPLAY_NAME`, `SAML_DISPLAY_NAME` and `OIDC_DISPLAY_NAME` being ignored ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18568))
+- Fix various typos in comments throughout the codebase ([luzpaz](https://github.com/mastodon/mastodon/pull/18604))
+- Fix CSV import error when rows include unicode characters ([HamptonMakes](https://github.com/mastodon/mastodon/pull/20592))
+
+### Security
+
+- Fix being able to spoof link verification ([Gargron](https://github.com/mastodon/mastodon/pull/20217))
+- Fix emoji substitution not applying only to text nodes in backend code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20641))
+- Fix emoji substitution not applying only to text nodes in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20640))
+- Fix rate limiting for paths with formats ([Gargron](https://github.com/mastodon/mastodon/pull/20675))
+- Fix out-of-bound reads in blurhash transcoder ([delroth](https://github.com/mastodon/mastodon/pull/20388))
+
+_For previous changes, review the [stable-3.5 branch](https://github.com/mastodon/mastodon/blob/stable-3.5/CHANGELOG.md)_
diff --git a/Dockerfile b/Dockerfile
index 119c266b89..8778133e0d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,7 +20,7 @@ FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
# Example: v4.2.0-nightly.2023.11.09+something
-# Overwrite existance of 'alpha.0' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
+# Overwrite existence of 'alpha.0' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
ARG MASTODON_VERSION_PRERELEASE=""
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="something"]
ARG MASTODON_VERSION_METADATA=""
@@ -29,7 +29,7 @@ ARG MASTODON_VERSION_METADATA=""
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
ARG RAILS_SERVE_STATIC_FILES="true"
# Allow to use YJIT compiler
-# See: https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md
+# See: https://github.com/ruby/ruby/blob/v3_2_3/doc/yjit/yjit.md
ARG RUBY_YJIT_ENABLE="1"
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
ARG TZ="Etc/UTC"
diff --git a/Gemfile b/Gemfile
index ad7f0b3d40..5dfaeaba9a 100644
--- a/Gemfile
+++ b/Gemfile
@@ -58,7 +58,9 @@ gem 'htmlentities', '~> 4.3'
gem 'http', '~> 5.1'
gem 'http_accept_language', '~> 2.1'
gem 'httplog', '~> 1.6.2'
+gem 'i18n', '1.14.1' # TODO: Remove version when resolved: https://github.com/glebm/i18n-tasks/issues/552 / https://github.com/ruby-i18n/i18n/pull/688
gem 'idn-ruby', require: 'idn'
+gem 'inline_svg'
gem 'kaminari', '~> 1.2'
gem 'link_header', '~> 0.0'
gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar'
@@ -88,7 +90,7 @@ gem 'sidekiq-bulk', '~> 0.2.0'
gem 'simple-navigation', '~> 4.4'
gem 'simple_form', '~> 5.2'
gem 'stoplight', '~> 3.0.1'
-gem 'strong_migrations', '1.7.0'
+gem 'strong_migrations', '1.8.0'
gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0'
gem 'tzinfo-data', '~> 1.2023'
@@ -112,7 +114,7 @@ group :test do
# RSpec helpers for email specs
gem 'email_spec'
- # Extra RSpec extenion methods and helpers for sidekiq
+ # Extra RSpec extension methods and helpers for sidekiq
gem 'rspec-sidekiq', '~> 4.0'
# Browser integration testing
@@ -125,12 +127,6 @@ group :test do
# Used to mock environment variables
gem 'climate_control'
- # Generating fake data for specs
- gem 'faker', '~> 3.2'
-
- # Generate test objects for specs
- gem 'fabrication', '~> 2.30'
-
# Add back helpers functions removed in Rails 5.1
gem 'rails-controller-testing', '~> 1.0'
@@ -182,6 +178,12 @@ group :development, :test do
# Interactive Debugging tools
gem 'debug', '~> 1.8'
+ # Generate fake data values
+ gem 'faker', '~> 3.2'
+
+ # Generate factory objects
+ gem 'fabrication', '~> 2.30'
+
# Profiling tools
gem 'memory_profiler', require: false
gem 'ruby-prof', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 0b53df82e0..b341ca84b3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -10,35 +10,35 @@ GIT
GEM
remote: https://rubygems.org/
specs:
- actioncable (7.1.3)
- actionpack (= 7.1.3)
- activesupport (= 7.1.3)
+ actioncable (7.1.3.2)
+ actionpack (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
- actionmailbox (7.1.3)
- actionpack (= 7.1.3)
- activejob (= 7.1.3)
- activerecord (= 7.1.3)
- activestorage (= 7.1.3)
- activesupport (= 7.1.3)
+ actionmailbox (7.1.3.2)
+ actionpack (= 7.1.3.2)
+ activejob (= 7.1.3.2)
+ activerecord (= 7.1.3.2)
+ activestorage (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
- actionmailer (7.1.3)
- actionpack (= 7.1.3)
- actionview (= 7.1.3)
- activejob (= 7.1.3)
- activesupport (= 7.1.3)
+ actionmailer (7.1.3.2)
+ actionpack (= 7.1.3.2)
+ actionview (= 7.1.3.2)
+ activejob (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.2)
- actionpack (7.1.3)
- actionview (= 7.1.3)
- activesupport (= 7.1.3)
+ actionpack (7.1.3.2)
+ actionview (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4)
@@ -46,15 +46,15 @@ GEM
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
- actiontext (7.1.3)
- actionpack (= 7.1.3)
- activerecord (= 7.1.3)
- activestorage (= 7.1.3)
- activesupport (= 7.1.3)
+ actiontext (7.1.3.2)
+ actionpack (= 7.1.3.2)
+ activerecord (= 7.1.3.2)
+ activestorage (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
- actionview (7.1.3)
- activesupport (= 7.1.3)
+ actionview (7.1.3.2)
+ activesupport (= 7.1.3.2)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
@@ -64,22 +64,22 @@ GEM
activemodel (>= 4.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
- activejob (7.1.3)
- activesupport (= 7.1.3)
+ activejob (7.1.3.2)
+ activesupport (= 7.1.3.2)
globalid (>= 0.3.6)
- activemodel (7.1.3)
- activesupport (= 7.1.3)
- activerecord (7.1.3)
- activemodel (= 7.1.3)
- activesupport (= 7.1.3)
+ activemodel (7.1.3.2)
+ activesupport (= 7.1.3.2)
+ activerecord (7.1.3.2)
+ activemodel (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
timeout (>= 0.4.0)
- activestorage (7.1.3)
- actionpack (= 7.1.3)
- activejob (= 7.1.3)
- activerecord (= 7.1.3)
- activesupport (= 7.1.3)
+ activestorage (7.1.3.2)
+ actionpack (= 7.1.3.2)
+ activejob (= 7.1.3.2)
+ activerecord (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
marcel (~> 1.0)
- activesupport (7.1.3)
+ activesupport (7.1.3.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -139,7 +139,7 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
- bigdecimal (3.1.6)
+ bigdecimal (3.1.7)
bindata (2.4.15)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
@@ -213,20 +213,19 @@ GEM
devise_pam_authenticatable2 (9.2.0)
devise (>= 4.0.0)
rpam2 (~> 4.0)
- diff-lcs (1.5.0)
+ diff-lcs (1.5.1)
discard (1.3.0)
activerecord (>= 4.2, < 8)
docile (1.4.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
- doorkeeper (5.6.8)
+ doorkeeper (5.6.9)
railties (>= 5)
dotenv (2.8.1)
dotenv-rails (2.8.1)
dotenv (= 2.8.1)
railties (>= 3.2)
- drb (2.2.0)
- ruby2_keywords
+ drb (2.2.1)
ed25519 (1.3.0)
elasticsearch (7.13.3)
elasticsearch-api (= 7.13.3)
@@ -309,7 +308,7 @@ GEM
activesupport (>= 5.1)
haml (>= 4.0.6)
railties (>= 5.1)
- haml_lint (0.56.0)
+ haml_lint (0.57.0)
haml (>= 5.0)
parallel (~> 1.10)
rainbow
@@ -333,7 +332,7 @@ GEM
http-form_data (2.3.0)
http_accept_language (2.1.1)
httpclient (2.8.3)
- httplog (1.6.2)
+ httplog (1.6.3)
rack (>= 2.0)
rainbow (>= 2.0.0)
i18n (1.14.1)
@@ -350,14 +349,17 @@ GEM
rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1)
idn-ruby (0.1.5)
+ inline_svg (1.9.0)
+ activesupport (>= 3.0)
+ nokogiri (>= 1.6)
io-console (0.7.2)
- irb (1.11.2)
+ irb (1.12.0)
rdoc
reline (>= 0.4.2)
jmespath (1.6.2)
json (2.7.1)
json-canonicalization (1.0.0)
- json-jwt (1.15.3)
+ json-jwt (1.15.3.1)
activesupport (>= 4.2)
aes_key_wrap
bindata
@@ -372,7 +374,7 @@ GEM
json-ld-preloaded (3.3.0)
json-ld (~> 3.3)
rdf (~> 3.3)
- json-schema (4.1.1)
+ json-schema (4.2.0)
addressable (>= 2.8)
jsonapi-renderer (0.2.2)
jwt (2.7.1)
@@ -435,7 +437,7 @@ GEM
mime-types-data (3.2023.1205)
mini_mime (1.1.5)
mini_portile2 (2.8.5)
- minitest (5.21.2)
+ minitest (5.22.3)
msgpack (1.7.2)
multi_json (1.15.0)
multipart-post (2.3.0)
@@ -444,7 +446,7 @@ GEM
uri
net-http-persistent (4.0.2)
connection_pool (~> 2.2)
- net-imap (0.4.9.1)
+ net-imap (0.4.10)
date
net-protocol
net-ldap (0.19.0)
@@ -455,7 +457,7 @@ GEM
net-smtp (0.4.0.1)
net-protocol
nio4r (2.5.9)
- nokogiri (1.16.2)
+ nokogiri (1.16.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nsa (0.3.0)
@@ -465,11 +467,11 @@ GEM
statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.16.3)
bigdecimal (>= 3.0)
- omniauth (2.1.1)
+ omniauth (2.1.2)
hashie (>= 3.4.6)
rack (>= 2.2.3)
rack-protection
- omniauth-cas (3.0.0.beta.1)
+ omniauth-cas (3.0.0)
addressable (~> 2.8)
nokogiri (~> 1.12)
omniauth (~> 2.1)
@@ -497,7 +499,7 @@ GEM
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
orm_adapter (0.5.0)
- ox (2.14.17)
+ ox (2.14.18)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
@@ -505,7 +507,7 @@ GEM
parslet (2.0.0)
pastel (0.8.0)
tty-color (~> 0.5)
- pg (1.5.5)
+ pg (1.5.6)
pghero (3.4.1)
activerecord (>= 6)
posix-spawn (0.3.15)
@@ -532,10 +534,10 @@ GEM
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.7.3)
- rack (2.2.8)
+ rack (2.2.9)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
- rack-cors (2.0.1)
+ rack-cors (2.0.2)
rack (>= 2.0.0)
rack-oauth2 (1.21.3)
activesupport
@@ -543,8 +545,9 @@ GEM
httpclient
json-jwt (>= 1.11.0)
rack (>= 2.1.0)
- rack-protection (3.0.5)
- rack
+ rack-protection (3.2.0)
+ base64 (>= 0.1.0)
+ rack (~> 2.2, >= 2.2.4)
rack-proxy (0.7.6)
rack
rack-session (1.0.2)
@@ -554,20 +557,20 @@ GEM
rackup (1.0.0)
rack (< 3)
webrick
- rails (7.1.3)
- actioncable (= 7.1.3)
- actionmailbox (= 7.1.3)
- actionmailer (= 7.1.3)
- actionpack (= 7.1.3)
- actiontext (= 7.1.3)
- actionview (= 7.1.3)
- activejob (= 7.1.3)
- activemodel (= 7.1.3)
- activerecord (= 7.1.3)
- activestorage (= 7.1.3)
- activesupport (= 7.1.3)
+ rails (7.1.3.2)
+ actioncable (= 7.1.3.2)
+ actionmailbox (= 7.1.3.2)
+ actionmailer (= 7.1.3.2)
+ actionpack (= 7.1.3.2)
+ actiontext (= 7.1.3.2)
+ actionview (= 7.1.3.2)
+ activejob (= 7.1.3.2)
+ activemodel (= 7.1.3.2)
+ activerecord (= 7.1.3.2)
+ activestorage (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
bundler (>= 1.15.0)
- railties (= 7.1.3)
+ railties (= 7.1.3.2)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@@ -579,12 +582,12 @@ GEM
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
- rails-i18n (7.0.8)
+ rails-i18n (7.0.9)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
- railties (7.1.3)
- actionpack (= 7.1.3)
- activesupport (= 7.1.3)
+ railties (7.1.3.2)
+ actionpack (= 7.1.3.2)
+ activesupport (= 7.1.3.2)
irb
rackup (>= 1.0.0)
rake (>= 12.2)
@@ -597,7 +600,7 @@ GEM
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.7.0)
rdf (~> 3.3)
- rdoc (6.6.2)
+ rdoc (6.6.3.1)
psych (>= 4.0.0)
redcarpet (3.6.0)
redis (4.8.1)
@@ -606,7 +609,7 @@ GEM
redlock (1.3.2)
redis (>= 3.0.0, < 6.0)
regexp_parser (2.9.0)
- reline (0.4.2)
+ reline (0.4.3)
io-console (~> 0.5)
request_store (1.5.1)
rack (>= 1.4)
@@ -621,31 +624,31 @@ GEM
chunky_png (~> 1.0)
rqrcode_core (~> 1.0)
rqrcode_core (1.2.0)
- rspec-core (3.12.2)
- rspec-support (~> 3.12.0)
- rspec-expectations (3.12.3)
+ rspec-core (3.13.0)
+ rspec-support (~> 3.13.0)
+ rspec-expectations (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.12.0)
+ rspec-support (~> 3.13.0)
rspec-github (2.4.0)
rspec-core (~> 3.0)
- rspec-mocks (3.12.6)
+ rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
- rspec-support (~> 3.12.0)
- rspec-rails (6.1.1)
+ rspec-support (~> 3.13.0)
+ rspec-rails (6.1.2)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
- rspec-core (~> 3.12)
- rspec-expectations (~> 3.12)
- rspec-mocks (~> 3.12)
- rspec-support (~> 3.12)
+ rspec-core (~> 3.13)
+ rspec-expectations (~> 3.13)
+ rspec-mocks (~> 3.13)
+ rspec-support (~> 3.13)
rspec-sidekiq (4.1.0)
rspec-core (~> 3.0)
rspec-expectations (~> 3.0)
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8)
- rspec-support (3.12.1)
- rubocop (1.60.2)
+ rspec-support (3.13.1)
+ rubocop (1.62.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@@ -653,24 +656,24 @@ GEM
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
- rubocop-ast (>= 1.30.0, < 2.0)
+ rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
- rubocop-ast (1.30.0)
- parser (>= 3.2.1.0)
+ rubocop-ast (1.31.2)
+ parser (>= 3.3.0.4)
rubocop-capybara (2.20.0)
rubocop (~> 1.41)
- rubocop-factory_bot (2.25.0)
- rubocop (~> 1.33)
+ rubocop-factory_bot (2.25.1)
+ rubocop (~> 1.41)
rubocop-performance (1.20.2)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
- rubocop-rails (2.23.1)
+ rubocop-rails (2.24.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
- rubocop-ast (>= 1.30.0, < 2.0)
- rubocop-rspec (2.26.1)
+ rubocop-ast (>= 1.31.1, < 2.0)
+ rubocop-rspec (2.27.1)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
@@ -691,7 +694,7 @@ GEM
scenic (1.7.0)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
- selenium-webdriver (4.17.0)
+ selenium-webdriver (4.18.1)
base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
@@ -731,7 +734,7 @@ GEM
stoplight (3.0.2)
redlock (~> 1.0)
stringio (3.1.0)
- strong_migrations (1.7.0)
+ strong_migrations (1.8.0)
activerecord (>= 5.2)
swd (1.3.0)
activesupport (>= 3)
@@ -743,8 +746,8 @@ GEM
unicode-display_width (>= 1.1.1, < 3)
terrapin (1.0.1)
climate_control
- test-prof (1.3.1)
- thor (1.3.0)
+ test-prof (1.3.2)
+ thor (1.3.1)
tilt (2.3.0)
timeout (0.4.1)
tpm-key_attestation (0.12.0)
@@ -793,7 +796,7 @@ GEM
webfinger (1.2.0)
activesupport
httpclient (>= 2.4)
- webmock (3.20.0)
+ webmock (3.22.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -811,7 +814,7 @@ GEM
xorcist (1.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.6.12)
+ zeitwerk (2.6.13)
PLATFORMS
ruby
@@ -862,8 +865,10 @@ DEPENDENCIES
http (~> 5.1)
http_accept_language (~> 2.1)
httplog (~> 1.6.2)
+ i18n (= 1.14.1)
i18n-tasks (~> 1.0)
idn-ruby
+ inline_svg
irb (~> 1.8)
json-ld
json-ld-preloaded (~> 3.2)
@@ -935,7 +940,7 @@ DEPENDENCIES
simplecov-lcov (~> 0.8)
stackprof
stoplight (~> 3.0.1)
- strong_migrations (= 1.7.0)
+ strong_migrations (= 1.8.0)
test-prof
thor (~> 1.2)
tty-prompt (~> 0.23)
diff --git a/README.md b/README.md
index 48ef5f0b9a..2221831248 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,6 @@
## Introduction
This Mastodon fork is based on the [glitch-soc Fork of Mastodon](https://github.com/glitch-soc/mastodon), with changes made to suit [CatCatNya~](https://catcatnya.com).
-The aforementioned instance is running the `develop` branch.
I intend to contribute some useful differences back to [glitch-soc](https://github.com/glitch-soc/mastodon) and [vanilla Mastodon](https://github.com/mastodon/mastodon).
To install, take a look at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/). The instructions and features are the same, except for the differences outlined below.
@@ -22,15 +21,15 @@ instead, use merge (fast-forward, if possible, with merge commit otherwise).
- sounds/boop.mp3
- sounds/boop.ogg
You might want to revert these to the upstream files (or your own versions!) if you decide to use this fork for your own instance.
-- The web frontend emoji picker is a blobcat instead of the joy emoji.
- The rate limits for authenticated users have been relaxed a bit.
- The API endpoint `/api/v1/custom_emojis` is no longer affected by AUTHORIZED_FETCH, allowing anyone to copy custom emojis.
-- Allow higher resolution images. (4096x4096 instead of the previous limit of 1920x1080)
+- Allow higher resolution images. (4096x4096 instead of the previous limit of 3840x2160)
- Allow posting polls with only one poll option (if `MIN_POLL_OPTIONS` is set to 1 on your instance).
-- Added oatstodon flavour (taken from [types.pl fork](https://github.com/ralsei/types.pl), by [@oat@hellsite.site](https://hellsite.site/@oat))
+- Added oatstodon flavour (taken from [types.pl fork](https://github.com/ralsei/types.pl), by [@oat@hellsite.site](https://hellsite.site/@oat)), with slight adjustments since.
- Emoji reactions on statuses (with both Unicode and custom emojis, same as for announcements), a feature originally developed for [Nyastodon](https://git.bsd.gay/fef/nyastodon).
Ended up as a Catstodon-maintained patch after its initial two Pull Requests to glitch-soc, but was handed over to [Essem's fork, Chuckya](https://github.com/TheEssem/mastodon) and is now pending [its fourth attempt of merging into glitch-soc](https://github.com/glitch-soc/mastodon/pull/2462).
- Lifts the "only federate local favourites" restriction on favourites/likes and emoji reactions.
+- Cherry-picks the [activity filter branch](https://github.com/chikorita157/mastodon-sakura/tree/newmain-tmp3-noellabo-filtering) from [Sakurajima Mastodon](https://github.com/chikorita157/mastodon-sakura).
## Previous differences now merged into glitch-soc
diff --git a/Vagrantfile b/Vagrantfile
index 6f0f511095..12bd1ba67a 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -188,7 +188,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.post_up_message = < { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
diff --git a/app/controllers/activitypub/followers_synchronizations_controller.rb b/app/controllers/activitypub/followers_synchronizations_controller.rb
index d2942104e5..392dd36bcd 100644
--- a/app/controllers/activitypub/followers_synchronizations_controller.rb
+++ b/app/controllers/activitypub/followers_synchronizations_controller.rb
@@ -1,9 +1,6 @@
# frozen_string_literal: true
class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseController
- include SignatureVerification
- include AccountOwnedConcern
-
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!
diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb
index ba85e0a722..49cfc8ad1c 100644
--- a/app/controllers/activitypub/inboxes_controller.rb
+++ b/app/controllers/activitypub/inboxes_controller.rb
@@ -1,9 +1,7 @@
# frozen_string_literal: true
class ActivityPub::InboxesController < ActivityPub::BaseController
- include SignatureVerification
include JsonLdHelper
- include AccountOwnedConcern
before_action :skip_unknown_actor_activity
before_action :require_actor_signature!
@@ -62,11 +60,10 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
return if raw_params.blank? || ENV['DISABLE_FOLLOWERS_SYNCHRONIZATION'] == 'true' || signed_request_account.nil?
# Re-using the syntax for signature parameters
- tree = SignatureParamsParser.new.parse(raw_params)
- params = SignatureParamsTransformer.new.apply(tree)
+ params = SignatureParser.parse(raw_params)
ActivityPub::PrepareFollowersSynchronizationService.new.call(signed_request_account, params)
- rescue Parslet::ParseFailed
+ rescue SignatureParser::ParsingError
Rails.logger.warn 'Error parsing Collection-Synchronization header'
end
diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb
index bf10ba762a..8079e011dd 100644
--- a/app/controllers/activitypub/outboxes_controller.rb
+++ b/app/controllers/activitypub/outboxes_controller.rb
@@ -3,9 +3,6 @@
class ActivityPub::OutboxesController < ActivityPub::BaseController
LIMIT = 20
- include SignatureVerification
- include AccountOwnedConcern
-
vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb
index c38ff89d1c..3f43e89a5e 100644
--- a/app/controllers/activitypub/replies_controller.rb
+++ b/app/controllers/activitypub/replies_controller.rb
@@ -1,9 +1,7 @@
# frozen_string_literal: true
class ActivityPub::RepliesController < ActivityPub::BaseController
- include SignatureVerification
include Authorization
- include AccountOwnedConcern
DESCENDANTS_LIMIT = 60
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb
index 9beb8fde6b..d3be7817ff 100644
--- a/app/controllers/admin/accounts_controller.rb
+++ b/app/controllers/admin/accounts_controller.rb
@@ -128,7 +128,7 @@ module Admin
def unblock_email
authorize @account, :unblock_email?
- CanonicalEmailBlock.where(reference_account: @account).delete_all
+ CanonicalEmailBlock.matching_account(@account).delete_all
log_action :unblock_email, @account
diff --git a/app/controllers/admin/rules_controller.rb b/app/controllers/admin/rules_controller.rb
index d31aec6ea8..b8def22ba3 100644
--- a/app/controllers/admin/rules_controller.rb
+++ b/app/controllers/admin/rules_controller.rb
@@ -53,7 +53,7 @@ module Admin
end
def resource_params
- params.require(:rule).permit(:text, :priority)
+ params.require(:rule).permit(:text, :hint, :priority)
end
end
end
diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb
index 98fa1897ef..f87d596ce3 100644
--- a/app/controllers/api/base_controller.rb
+++ b/app/controllers/api/base_controller.rb
@@ -8,6 +8,7 @@ class Api::BaseController < ApplicationController
include Api::AccessTokenTrackingConcern
include Api::CachingConcern
include Api::ContentSecurityPolicy
+ include Api::ErrorHandling
skip_before_action :require_functional!, unless: :limited_federation_mode?
@@ -18,51 +19,6 @@ class Api::BaseController < ApplicationController
protect_from_forgery with: :null_session
- rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
- render json: { error: e.to_s }, status: 422
- end
-
- rescue_from ActiveRecord::RecordNotUnique do
- render json: { error: 'Duplicate record' }, status: 422
- end
-
- rescue_from Date::Error do
- render json: { error: 'Invalid date supplied' }, status: 422
- end
-
- rescue_from ActiveRecord::RecordNotFound do
- render json: { error: 'Record not found' }, status: 404
- end
-
- rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
- render json: { error: 'Remote data could not be fetched' }, status: 503
- end
-
- rescue_from OpenSSL::SSL::SSLError do
- render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
- end
-
- rescue_from Mastodon::NotPermittedError do
- render json: { error: 'This action is not allowed' }, status: 403
- end
-
- rescue_from Seahorse::Client::NetworkingError do |e|
- Rails.logger.warn "Storage server error: #{e}"
- render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
- end
-
- rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
- render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
- end
-
- rescue_from Mastodon::RateLimitExceededError do
- render json: { error: I18n.t('errors.429') }, status: 429
- end
-
- rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e|
- render json: { error: e.to_s }, status: 400
- end
-
def doorkeeper_unauthorized_render_options(error: nil)
{ json: { error: error.try(:description) || 'Not authorized' } }
end
@@ -73,6 +29,14 @@ class Api::BaseController < ApplicationController
protected
+ def pagination_max_id
+ pagination_collection.last.id
+ end
+
+ def pagination_since_id
+ pagination_collection.first.id
+ end
+
def set_pagination_headers(next_path = nil, prev_path = nil)
links = []
links << [next_path, [%w(rel next)]] if next_path
@@ -140,6 +104,10 @@ class Api::BaseController < ApplicationController
private
+ def insert_pagination_headers
+ set_pagination_headers(next_path, prev_path)
+ end
+
def pagination_options_invalid?
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
end
diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
index f60181f1eb..449866fa55 100644
--- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb
@@ -41,10 +41,6 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_account_followers_url pagination_params(max_id: pagination_max_id) if records_continue?
end
diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb
index 3ab8c1efd6..c4f4313f8f 100644
--- a/app/controllers/api/v1/accounts/following_accounts_controller.rb
+++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb
@@ -41,10 +41,6 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_account_following_index_url pagination_params(max_id: pagination_max_id) if records_continue?
end
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index fe4279302f..35ea9c8ec1 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -4,7 +4,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
before_action -> { authorize_if_got_token! :read, :'read:statuses' }
before_action :set_account
- after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) }
+ after_action :insert_pagination_headers
def index
cache_if_unauthenticated!
@@ -35,10 +35,6 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
params.slice(:limit, *AccountStatusesFilter::KEYS).permit(:limit, *AccountStatusesFilter::KEYS).merge(core_params)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_account_statuses_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -51,11 +47,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end
- def pagination_max_id
- @statuses.last.id
- end
-
- def pagination_since_id
- @statuses.first.id
+ def pagination_collection
+ @statuses
end
end
diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb
index ff9cae6398..ff6f41e01d 100644
--- a/app/controllers/api/v1/admin/accounts_controller.rb
+++ b/app/controllers/api/v1/admin/accounts_controller.rb
@@ -125,10 +125,6 @@ class Api::V1::Admin::AccountsController < Api::BaseController
translated_params
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_accounts_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -137,12 +133,8 @@ class Api::V1::Admin::AccountsController < Api::BaseController
api_v1_admin_accounts_url(pagination_params(min_id: pagination_since_id)) unless @accounts.empty?
end
- def pagination_max_id
- @accounts.last.id
- end
-
- def pagination_since_id
- @accounts.first.id
+ def pagination_collection
+ @accounts
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb b/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb
index 7b192b979f..701f668de6 100644
--- a/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb
+++ b/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb
@@ -65,10 +65,6 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController
@canonical_email_block = CanonicalEmailBlock.find(params[:id])
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_canonical_email_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -77,12 +73,8 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController
api_v1_admin_canonical_email_blocks_url(pagination_params(min_id: pagination_since_id)) unless @canonical_email_blocks.empty?
end
- def pagination_max_id
- @canonical_email_blocks.last.id
- end
-
- def pagination_since_id
- @canonical_email_blocks.first.id
+ def pagination_collection
+ @canonical_email_blocks
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/domain_allows_controller.rb b/app/controllers/api/v1/admin/domain_allows_controller.rb
index dd54d67106..a7ae84e306 100644
--- a/app/controllers/api/v1/admin/domain_allows_controller.rb
+++ b/app/controllers/api/v1/admin/domain_allows_controller.rb
@@ -61,10 +61,6 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
DomainAllow.all
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_domain_allows_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -73,12 +69,8 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
api_v1_admin_domain_allows_url(pagination_params(min_id: pagination_since_id)) unless @domain_allows.empty?
end
- def pagination_max_id
- @domain_allows.last.id
- end
-
- def pagination_since_id
- @domain_allows.first.id
+ def pagination_collection
+ @domain_allows
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/domain_blocks_controller.rb b/app/controllers/api/v1/admin/domain_blocks_controller.rb
index 2538c7c7c2..b589d277d5 100644
--- a/app/controllers/api/v1/admin/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/admin/domain_blocks_controller.rb
@@ -72,10 +72,6 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
params.permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_domain_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -84,12 +80,8 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
api_v1_admin_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @domain_blocks.empty?
end
- def pagination_max_id
- @domain_blocks.last.id
- end
-
- def pagination_since_id
- @domain_blocks.first.id
+ def pagination_collection
+ @domain_blocks
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/email_domain_blocks_controller.rb b/app/controllers/api/v1/admin/email_domain_blocks_controller.rb
index df54b9f0a4..bdedb9d040 100644
--- a/app/controllers/api/v1/admin/email_domain_blocks_controller.rb
+++ b/app/controllers/api/v1/admin/email_domain_blocks_controller.rb
@@ -58,10 +58,6 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
params.permit(:domain, :allow_with_approval)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_email_domain_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -70,12 +66,8 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
api_v1_admin_email_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @email_domain_blocks.empty?
end
- def pagination_max_id
- @email_domain_blocks.last.id
- end
-
- def pagination_since_id
- @email_domain_blocks.first.id
+ def pagination_collection
+ @email_domain_blocks
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/ip_blocks_controller.rb b/app/controllers/api/v1/admin/ip_blocks_controller.rb
index 61c1912344..3625781149 100644
--- a/app/controllers/api/v1/admin/ip_blocks_controller.rb
+++ b/app/controllers/api/v1/admin/ip_blocks_controller.rb
@@ -63,10 +63,6 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
params.permit(:ip, :severity, :comment, :expires_in)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_ip_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -75,12 +71,8 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
api_v1_admin_ip_blocks_url(pagination_params(min_id: pagination_since_id)) unless @ip_blocks.empty?
end
- def pagination_max_id
- @ip_blocks.last.id
- end
-
- def pagination_since_id
- @ip_blocks.first.id
+ def pagination_collection
+ @ip_blocks
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/reports_controller.rb b/app/controllers/api/v1/admin/reports_controller.rb
index 9dfb181a28..9b5beeab67 100644
--- a/app/controllers/api/v1/admin/reports_controller.rb
+++ b/app/controllers/api/v1/admin/reports_controller.rb
@@ -35,6 +35,7 @@ class Api::V1::Admin::ReportsController < Api::BaseController
def update
authorize @report, :update?
@report.update!(report_params)
+ log_action :update, @report
render json: @report, serializer: REST::Admin::ReportSerializer
end
@@ -88,10 +89,6 @@ class Api::V1::Admin::ReportsController < Api::BaseController
params.permit(*FILTER_PARAMS)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_reports_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -100,12 +97,8 @@ class Api::V1::Admin::ReportsController < Api::BaseController
api_v1_admin_reports_url(pagination_params(min_id: pagination_since_id)) unless @reports.empty?
end
- def pagination_max_id
- @reports.last.id
- end
-
- def pagination_since_id
- @reports.first.id
+ def pagination_collection
+ @reports
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/tags_controller.rb b/app/controllers/api/v1/admin/tags_controller.rb
index 6a7c9f5bf3..c754980720 100644
--- a/app/controllers/api/v1/admin/tags_controller.rb
+++ b/app/controllers/api/v1/admin/tags_controller.rb
@@ -44,10 +44,6 @@ class Api::V1::Admin::TagsController < Api::BaseController
params.permit(:display_name, :trendable, :usable, :listable)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_tags_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -56,12 +52,8 @@ class Api::V1::Admin::TagsController < Api::BaseController
api_v1_admin_tags_url(pagination_params(min_id: pagination_since_id)) unless @tags.empty?
end
- def pagination_max_id
- @tags.last.id
- end
-
- def pagination_since_id
- @tags.first.id
+ def pagination_collection
+ @tags
end
def records_continue?
diff --git a/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb b/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb
index 5d9fcc82c0..8bb5e22716 100644
--- a/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb
+++ b/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb
@@ -42,10 +42,6 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC
@providers = PreviewCardProvider.all.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
@@ -54,12 +50,8 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(min_id: pagination_since_id)) unless @providers.empty?
end
- def pagination_max_id
- @providers.last.id
- end
-
- def pagination_since_id
- @providers.first.id
+ def pagination_collection
+ @providers
end
def records_continue?
diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb
index 0934622f88..234ab2e82c 100644
--- a/app/controllers/api/v1/blocks_controller.rb
+++ b/app/controllers/api/v1/blocks_controller.rb
@@ -28,10 +28,6 @@ class Api::V1::BlocksController < Api::BaseController
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_blocks_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -40,12 +36,8 @@ class Api::V1::BlocksController < Api::BaseController
api_v1_blocks_url pagination_params(since_id: pagination_since_id) unless paginated_blocks.empty?
end
- def pagination_max_id
- paginated_blocks.last.id
- end
-
- def pagination_since_id
- paginated_blocks.first.id
+ def pagination_collection
+ paginated_blocks
end
def records_continue?
diff --git a/app/controllers/api/v1/bookmarks_controller.rb b/app/controllers/api/v1/bookmarks_controller.rb
index 498eb16f44..b6bb987b6b 100644
--- a/app/controllers/api/v1/bookmarks_controller.rb
+++ b/app/controllers/api/v1/bookmarks_controller.rb
@@ -31,10 +31,6 @@ class Api::V1::BookmarksController < Api::BaseController
current_account.bookmarks
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_bookmarks_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -43,12 +39,8 @@ class Api::V1::BookmarksController < Api::BaseController
api_v1_bookmarks_url pagination_params(min_id: pagination_since_id) unless results.empty?
end
- def pagination_max_id
- results.last.id
- end
-
- def pagination_since_id
- results.first.id
+ def pagination_collection
+ results
end
def records_continue?
diff --git a/app/controllers/api/v1/conversations_controller.rb b/app/controllers/api/v1/conversations_controller.rb
index 6a3567e624..a95c816e1c 100644
--- a/app/controllers/api/v1/conversations_controller.rb
+++ b/app/controllers/api/v1/conversations_controller.rb
@@ -53,10 +53,6 @@ class Api::V1::ConversationsController < Api::BaseController
.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_conversations_url pagination_params(max_id: pagination_max_id) if records_continue?
end
diff --git a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb
index 68cf4384f7..d3de220393 100644
--- a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb
+++ b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb
@@ -29,10 +29,6 @@ class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
@encrypted_messages = @current_device.encrypted_messages.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_crypto_encrypted_messages_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -41,12 +37,8 @@ class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
api_v1_crypto_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty?
end
- def pagination_max_id
- @encrypted_messages.last.id
- end
-
- def pagination_since_id
- @encrypted_messages.first.id
+ def pagination_collection
+ @encrypted_messages
end
def records_continue?
diff --git a/app/controllers/api/v1/domain_blocks_controller.rb b/app/controllers/api/v1/domain_blocks_controller.rb
index 34def3c44a..3dee2d176c 100644
--- a/app/controllers/api/v1/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/domain_blocks_controller.rb
@@ -38,10 +38,6 @@ class Api::V1::DomainBlocksController < Api::BaseController
current_account.domain_blocks
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_domain_blocks_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -50,12 +46,8 @@ class Api::V1::DomainBlocksController < Api::BaseController
api_v1_domain_blocks_url pagination_params(since_id: pagination_since_id) unless @blocks.empty?
end
- def pagination_max_id
- @blocks.last.id
- end
-
- def pagination_since_id
- @blocks.first.id
+ def pagination_collection
+ @blocks
end
def records_continue?
diff --git a/app/controllers/api/v1/endorsements_controller.rb b/app/controllers/api/v1/endorsements_controller.rb
index 2216a9860d..9a723d89e4 100644
--- a/app/controllers/api/v1/endorsements_controller.rb
+++ b/app/controllers/api/v1/endorsements_controller.rb
@@ -28,10 +28,6 @@ class Api::V1::EndorsementsController < Api::BaseController
current_account.endorsed_accounts.includes(:account_stat, :user).without_suspended
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
return if unlimited?
@@ -44,12 +40,8 @@ class Api::V1::EndorsementsController < Api::BaseController
api_v1_endorsements_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
end
- def pagination_max_id
- @accounts.last.id
- end
-
- def pagination_since_id
- @accounts.first.id
+ def pagination_collection
+ @accounts
end
def records_continue?
diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb
index faf1bda96a..73da538f5c 100644
--- a/app/controllers/api/v1/favourites_controller.rb
+++ b/app/controllers/api/v1/favourites_controller.rb
@@ -31,10 +31,6 @@ class Api::V1::FavouritesController < Api::BaseController
current_account.favourites
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_favourites_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -43,12 +39,8 @@ class Api::V1::FavouritesController < Api::BaseController
api_v1_favourites_url pagination_params(min_id: pagination_since_id) unless results.empty?
end
- def pagination_max_id
- results.last.id
- end
-
- def pagination_since_id
- results.first.id
+ def pagination_collection
+ results
end
def records_continue?
diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb
index 76633210a1..4f732ed2d5 100644
--- a/app/controllers/api/v1/featured_tags/suggestions_controller.rb
+++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb
@@ -12,6 +12,10 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
private
def set_recently_used_tags
- @recently_used_tags = Tag.recently_used(current_account).where.not(id: current_account.featured_tags).limit(10)
+ @recently_used_tags = Tag.recently_used(current_account).where.not(id: featured_tag_ids).limit(10)
+ end
+
+ def featured_tag_ids
+ current_account.featured_tags.pluck(:tag_id)
end
end
diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb
index 87f6df5f94..7ffd7614bb 100644
--- a/app/controllers/api/v1/follow_requests_controller.rb
+++ b/app/controllers/api/v1/follow_requests_controller.rb
@@ -48,10 +48,6 @@ class Api::V1::FollowRequestsController < Api::BaseController
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_follow_requests_url pagination_params(max_id: pagination_max_id) if records_continue?
end
diff --git a/app/controllers/api/v1/followed_tags_controller.rb b/app/controllers/api/v1/followed_tags_controller.rb
index eae2bdc010..8888612b16 100644
--- a/app/controllers/api/v1/followed_tags_controller.rb
+++ b/app/controllers/api/v1/followed_tags_controller.rb
@@ -22,10 +22,6 @@ class Api::V1::FollowedTagsController < Api::BaseController
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_followed_tags_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -34,12 +30,8 @@ class Api::V1::FollowedTagsController < Api::BaseController
api_v1_followed_tags_url pagination_params(since_id: pagination_since_id) unless @results.empty?
end
- def pagination_max_id
- @results.last.id
- end
-
- def pagination_since_id
- @results.first.id
+ def pagination_collection
+ @results
end
def records_continue?
diff --git a/app/controllers/api/v1/lists/accounts_controller.rb b/app/controllers/api/v1/lists/accounts_controller.rb
index 0604ad60fc..aecf391049 100644
--- a/app/controllers/api/v1/lists/accounts_controller.rb
+++ b/app/controllers/api/v1/lists/accounts_controller.rb
@@ -55,10 +55,6 @@ class Api::V1::Lists::AccountsController < Api::BaseController
params.permit(account_ids: [])
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
return if unlimited?
@@ -71,12 +67,8 @@ class Api::V1::Lists::AccountsController < Api::BaseController
api_v1_list_accounts_url pagination_params(since_id: pagination_since_id) unless @accounts.empty?
end
- def pagination_max_id
- @accounts.last.id
- end
-
- def pagination_since_id
- @accounts.first.id
+ def pagination_collection
+ @accounts
end
def records_continue?
diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb
index 2fb685ac39..dbfd7e103a 100644
--- a/app/controllers/api/v1/mutes_controller.rb
+++ b/app/controllers/api/v1/mutes_controller.rb
@@ -28,10 +28,6 @@ class Api::V1::MutesController < Api::BaseController
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_mutes_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -40,12 +36,8 @@ class Api::V1::MutesController < Api::BaseController
api_v1_mutes_url pagination_params(since_id: pagination_since_id) unless paginated_mutes.empty?
end
- def pagination_max_id
- paginated_mutes.last.id
- end
-
- def pagination_since_id
- paginated_mutes.first.id
+ def pagination_collection
+ paginated_mutes
end
def records_continue?
diff --git a/app/controllers/api/v1/notifications/policies_controller.rb b/app/controllers/api/v1/notifications/policies_controller.rb
new file mode 100644
index 0000000000..1ec336f9a5
--- /dev/null
+++ b/app/controllers/api/v1/notifications/policies_controller.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+class Api::V1::Notifications::PoliciesController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :show
+ before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: :update
+
+ before_action :require_user!
+ before_action :set_policy
+
+ def show
+ render json: @policy, serializer: REST::NotificationPolicySerializer
+ end
+
+ def update
+ @policy.update!(resource_params)
+ render json: @policy, serializer: REST::NotificationPolicySerializer
+ end
+
+ private
+
+ def set_policy
+ @policy = NotificationPolicy.find_or_initialize_by(account: current_account)
+
+ with_read_replica do
+ @policy.summarize!
+ end
+ end
+
+ def resource_params
+ params.permit(
+ :filter_not_following,
+ :filter_not_followers,
+ :filter_new_accounts,
+ :filter_private_mentions
+ )
+ end
+end
diff --git a/app/controllers/api/v1/notifications/requests_controller.rb b/app/controllers/api/v1/notifications/requests_controller.rb
new file mode 100644
index 0000000000..6a26cc0e8a
--- /dev/null
+++ b/app/controllers/api/v1/notifications/requests_controller.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+class Api::V1::Notifications::RequestsController < Api::BaseController
+ before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :index
+ before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, except: :index
+
+ before_action :require_user!
+ before_action :set_request, except: :index
+
+ after_action :insert_pagination_headers, only: :index
+
+ def index
+ with_read_replica do
+ @requests = load_requests
+ @relationships = relationships
+ end
+
+ render json: @requests, each_serializer: REST::NotificationRequestSerializer, relationships: @relationships
+ end
+
+ def show
+ render json: @request, serializer: REST::NotificationRequestSerializer
+ end
+
+ def accept
+ AcceptNotificationRequestService.new.call(@request)
+ render_empty
+ end
+
+ def dismiss
+ @request.update!(dismissed: true)
+ render_empty
+ end
+
+ private
+
+ def load_requests
+ requests = NotificationRequest.where(account: current_account).where(dismissed: truthy_param?(:dismissed) || false).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id(
+ limit_param(DEFAULT_ACCOUNTS_LIMIT),
+ params_slice(:max_id, :since_id, :min_id)
+ )
+
+ NotificationRequest.preload_cache_collection(requests) do |statuses|
+ cache_collection(statuses, Status)
+ end
+ end
+
+ def relationships
+ StatusRelationshipsPresenter.new(@requests.map(&:last_status), current_user&.account_id)
+ end
+
+ def set_request
+ @request = NotificationRequest.where(account: current_account).find(params[:id])
+ end
+
+ def next_path
+ api_v1_notifications_requests_url pagination_params(max_id: pagination_max_id) unless @requests.empty?
+ end
+
+ def prev_path
+ api_v1_notifications_requests_url pagination_params(min_id: pagination_since_id) unless @requests.empty?
+ end
+
+ def pagination_max_id
+ @requests.last.id
+ end
+
+ def pagination_since_id
+ @requests.first.id
+ end
+
+ def pagination_params(core_params)
+ params.slice(:dismissed).permit(:dismissed).merge(core_params)
+ end
+end
diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb
index b1814e16ab..9c75516159 100644
--- a/app/controllers/api/v1/notifications_controller.rb
+++ b/app/controllers/api/v1/notifications_controller.rb
@@ -58,7 +58,8 @@ class Api::V1::NotificationsController < Api::BaseController
current_account.notifications.without_suspended.browserable(
types: Array(browserable_params[:types]),
exclude_types: Array(browserable_params[:exclude_types]),
- from_account_id: browserable_params[:account_id]
+ from_account_id: browserable_params[:account_id],
+ include_filtered: truthy_param?(:include_filtered)
)
end
@@ -66,10 +67,6 @@ class Api::V1::NotificationsController < Api::BaseController
@notifications.reject { |notification| notification.target_status.nil? }.map(&:target_status)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_notifications_url pagination_params(max_id: pagination_max_id) unless @notifications.empty?
end
@@ -78,19 +75,15 @@ class Api::V1::NotificationsController < Api::BaseController
api_v1_notifications_url pagination_params(min_id: pagination_since_id) unless @notifications.empty?
end
- def pagination_max_id
- @notifications.last.id
- end
-
- def pagination_since_id
- @notifications.first.id
+ def pagination_collection
+ @notifications
end
def browserable_params
- params.permit(:account_id, types: [], exclude_types: [])
+ params.permit(:account_id, :include_filtered, types: [], exclude_types: [])
end
def pagination_params(core_params)
- params.slice(:limit, :account_id, :types, :exclude_types).permit(:limit, :account_id, types: [], exclude_types: []).merge(core_params)
+ params.slice(:limit, :account_id, :types, :exclude_types, :include_filtered).permit(:limit, :account_id, :include_filtered, types: [], exclude_types: []).merge(core_params)
end
end
diff --git a/app/controllers/api/v1/scheduled_statuses_controller.rb b/app/controllers/api/v1/scheduled_statuses_controller.rb
index 2220b6d22e..1217ed014e 100644
--- a/app/controllers/api/v1/scheduled_statuses_controller.rb
+++ b/app/controllers/api/v1/scheduled_statuses_controller.rb
@@ -47,10 +47,6 @@ class Api::V1::ScheduledStatusesController < Api::BaseController
params.slice(:limit).permit(:limit).merge(core_params)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id) if records_continue?
end
@@ -63,11 +59,7 @@ class Api::V1::ScheduledStatusesController < Api::BaseController
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end
- def pagination_max_id
- @statuses.last.id
- end
-
- def pagination_since_id
- @statuses.first.id
+ def pagination_collection
+ @statuses
end
end
diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
index 069ad37cb2..bbc8082e0c 100644
--- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb
@@ -34,10 +34,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::V1::Statuses::Bas
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_status_favourited_by_index_url pagination_params(max_id: pagination_max_id) if records_continue?
end
diff --git a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
index b8a997518d..eaa5ef7255 100644
--- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
+++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb
@@ -30,10 +30,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::V1::Statuses::Base
)
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def next_path
api_v1_status_reblogged_by_index_url pagination_params(max_id: pagination_max_id) if records_continue?
end
diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb
index 960f8cf765..75e075be74 100644
--- a/app/controllers/api/v1/statuses_controller.rb
+++ b/app/controllers/api/v1/statuses_controller.rb
@@ -72,13 +72,9 @@ class Api::V1::StatusesController < Api::BaseController
with_rate_limit: true
)
- render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
+ render json: @status, serializer: serializer_for_status
rescue PostStatusService::UnexpectedMentionsError => e
- unexpected_accounts = ActiveModel::Serializer::CollectionSerializer.new(
- e.accounts,
- serializer: REST::AccountSerializer
- )
- render json: { error: e.message, unexpected_accounts: unexpected_accounts }, status: 422
+ render json: unexpected_accounts_error_json(e), status: 422
end
def update
@@ -158,6 +154,21 @@ class Api::V1::StatusesController < Api::BaseController
)
end
+ def serializer_for_status
+ @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
+ end
+
+ def unexpected_accounts_error_json(error)
+ {
+ error: error.message,
+ unexpected_accounts: serialized_accounts(error.accounts),
+ }
+ end
+
+ def serialized_accounts(accounts)
+ ActiveModel::Serializer::CollectionSerializer.new(accounts, serializer: REST::AccountSerializer)
+ end
+
def pagination_params(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
diff --git a/app/controllers/api/v1/timelines/base_controller.rb b/app/controllers/api/v1/timelines/base_controller.rb
index 173e173cc9..e79eba79ee 100644
--- a/app/controllers/api/v1/timelines/base_controller.rb
+++ b/app/controllers/api/v1/timelines/base_controller.rb
@@ -5,16 +5,8 @@ class Api::V1::Timelines::BaseController < Api::BaseController
private
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
- def pagination_max_id
- @statuses.last.id
- end
-
- def pagination_since_id
- @statuses.first.id
+ def pagination_collection
+ @statuses
end
def next_path_params
diff --git a/app/controllers/api/v1/trends/links_controller.rb b/app/controllers/api/v1/trends/links_controller.rb
index 57cfa0b7e4..8edf5bbcef 100644
--- a/app/controllers/api/v1/trends/links_controller.rb
+++ b/app/controllers/api/v1/trends/links_controller.rb
@@ -34,10 +34,6 @@ class Api::V1::Trends::LinksController < Api::BaseController
scope
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def pagination_params(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
diff --git a/app/controllers/api/v1/trends/statuses_controller.rb b/app/controllers/api/v1/trends/statuses_controller.rb
index 5485c450d0..d9db4176bf 100644
--- a/app/controllers/api/v1/trends/statuses_controller.rb
+++ b/app/controllers/api/v1/trends/statuses_controller.rb
@@ -33,10 +33,6 @@ class Api::V1::Trends::StatusesController < Api::BaseController
scope
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def pagination_params(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
diff --git a/app/controllers/api/v1/trends/tags_controller.rb b/app/controllers/api/v1/trends/tags_controller.rb
index 6cc8194def..0d8e27552e 100644
--- a/app/controllers/api/v1/trends/tags_controller.rb
+++ b/app/controllers/api/v1/trends/tags_controller.rb
@@ -30,10 +30,6 @@ class Api::V1::Trends::TagsController < Api::BaseController
Trends.tags.query.allowed
end
- def insert_pagination_headers
- set_pagination_headers(next_path, prev_path)
- end
-
def pagination_params(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 00f5c7c11e..c76110dba7 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -131,7 +131,7 @@ class ApplicationController < ActionController::Base
end
def single_user_mode?
- @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.where('id > 0').exists?
+ @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.without_internal.exists?
end
def use_seamless_external_login?
@@ -180,7 +180,7 @@ class ApplicationController < ActionController::Base
use_pack 'error'
render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html]
end
- format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: code }
+ format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: 410 }
end
end
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index 41c8562363..67d369b859 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -188,7 +188,9 @@ class Auth::SessionsController < Devise::SessionsController
)
# Only send a notification email every hour at most
- return if redis.set("2fa_failure_notification:#{user.id}", '1', ex: 1.hour, get: true).present?
+ return if redis.get("2fa_failure_notification:#{user.id}").present?
+
+ redis.set("2fa_failure_notification:#{user.id}", '1', ex: 1.hour)
UserMailer.failed_2fa(user, request.remote_ip, request.user_agent, Time.now.utc).deliver_later!
end
diff --git a/app/controllers/concerns/api/error_handling.rb b/app/controllers/concerns/api/error_handling.rb
new file mode 100644
index 0000000000..ad559fe2d7
--- /dev/null
+++ b/app/controllers/concerns/api/error_handling.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module Api::ErrorHandling
+ extend ActiveSupport::Concern
+
+ included do
+ rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
+ render json: { error: e.to_s }, status: 422
+ end
+
+ rescue_from ActiveRecord::RecordNotUnique do
+ render json: { error: 'Duplicate record' }, status: 422
+ end
+
+ rescue_from Date::Error do
+ render json: { error: 'Invalid date supplied' }, status: 422
+ end
+
+ rescue_from ActiveRecord::RecordNotFound do
+ render json: { error: 'Record not found' }, status: 404
+ end
+
+ rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do
+ render json: { error: 'Remote data could not be fetched' }, status: 503
+ end
+
+ rescue_from OpenSSL::SSL::SSLError do
+ render json: { error: 'Remote SSL certificate could not be verified' }, status: 503
+ end
+
+ rescue_from Mastodon::NotPermittedError do
+ render json: { error: 'This action is not allowed' }, status: 403
+ end
+
+ rescue_from Seahorse::Client::NetworkingError do |e|
+ Rails.logger.warn "Storage server error: #{e}"
+ render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
+ end
+
+ rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do
+ render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503
+ end
+
+ rescue_from Mastodon::RateLimitExceededError do
+ render json: { error: I18n.t('errors.429') }, status: 429
+ end
+
+ rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e|
+ render json: { error: e.to_s }, status: 400
+ end
+ end
+end
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb
index 92f1eb5a16..3155866271 100644
--- a/app/controllers/concerns/signature_verification.rb
+++ b/app/controllers/concerns/signature_verification.rb
@@ -12,39 +12,6 @@ module SignatureVerification
class SignatureVerificationError < StandardError; end
- class SignatureParamsParser < Parslet::Parser
- rule(:token) { match("[0-9a-zA-Z!#$%&'*+.^_`|~-]").repeat(1).as(:token) }
- rule(:quoted_string) { str('"') >> (qdtext | quoted_pair).repeat.as(:quoted_string) >> str('"') }
- # qdtext and quoted_pair are not exactly according to spec but meh
- rule(:qdtext) { match('[^\\\\"]') }
- rule(:quoted_pair) { str('\\') >> any }
- rule(:bws) { match('\s').repeat }
- rule(:param) { (token.as(:key) >> bws >> str('=') >> bws >> (token | quoted_string).as(:value)).as(:param) }
- rule(:comma) { bws >> str(',') >> bws }
- # Old versions of node-http-signature add an incorrect "Signature " prefix to the header
- rule(:buggy_prefix) { str('Signature ') }
- rule(:params) { buggy_prefix.maybe >> (param >> (comma >> param).repeat).as(:params) }
- root(:params)
- end
-
- class SignatureParamsTransformer < Parslet::Transform
- rule(params: subtree(:param)) do
- (param.is_a?(Array) ? param : [param]).each_with_object({}) { |(key, value), hash| hash[key] = value }
- end
-
- rule(param: { key: simple(:key), value: simple(:val) }) do
- [key, val]
- end
-
- rule(quoted_string: simple(:string)) do
- string.to_s
- end
-
- rule(token: simple(:string)) do
- string.to_s
- end
- end
-
def require_account_signature!
render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account
end
@@ -135,12 +102,8 @@ module SignatureVerification
end
def signature_params
- @signature_params ||= begin
- raw_signature = request.headers['Signature']
- tree = SignatureParamsParser.new.parse(raw_signature)
- SignatureParamsTransformer.new.apply(tree)
- end
- rescue Parslet::ParseFailed
+ @signature_params ||= SignatureParser.parse(request.headers['Signature'])
+ rescue SignatureParser::ParsingError
raise SignatureVerificationError, 'Error parsing signature parameters'
end
diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb
index 62f8e0d772..eb6417698a 100644
--- a/app/controllers/custom_css_controller.rb
+++ b/app/controllers/custom_css_controller.rb
@@ -16,6 +16,6 @@ class CustomCssController < ActionController::Base # rubocop:disable Rails/Appli
helper_method :custom_css_styles
def set_user_roles
- @user_roles = UserRole.where(highlighted: true).where.not(color: [nil, ''])
+ @user_roles = UserRole.providing_styles
end
end
diff --git a/app/controllers/instance_actors_controller.rb b/app/controllers/instance_actors_controller.rb
index 8422d74bc3..f2b1eaa3e7 100644
--- a/app/controllers/instance_actors_controller.rb
+++ b/app/controllers/instance_actors_controller.rb
@@ -6,6 +6,8 @@ class InstanceActorsController < ActivityPub::BaseController
serialization_scope nil
before_action :set_account
+
+ skip_before_action :authenticate_user! # From `AccountOwnedConcern`
skip_before_action :require_functional!
skip_before_action :update_user_sign_in
@@ -16,6 +18,11 @@ class InstanceActorsController < ActivityPub::BaseController
private
+ # Skips various `before_action` from `AccountOwnedConcern`
+ def account_required?
+ false
+ end
+
def set_account
@account = Account.representative
end
diff --git a/app/controllers/intents_controller.rb b/app/controllers/intents_controller.rb
index ea024e30e6..65c315208d 100644
--- a/app/controllers/intents_controller.rb
+++ b/app/controllers/intents_controller.rb
@@ -1,27 +1,26 @@
# frozen_string_literal: true
class IntentsController < ApplicationController
- before_action :check_uri
+ EXPECTED_SCHEME = 'web+mastodon'
+ before_action :handle_invalid_uri, unless: :valid_uri?
rescue_from Addressable::URI::InvalidURIError, with: :handle_invalid_uri
def show
- if uri.scheme == 'web+mastodon'
- case uri.host
- when 'follow'
- return redirect_to authorize_interaction_path(uri: uri.query_values['uri'].delete_prefix('acct:'))
- when 'share'
- return redirect_to share_path(text: uri.query_values['text'])
- end
+ case uri.host
+ when 'follow'
+ redirect_to authorize_interaction_path(uri: uri.query_values['uri'].delete_prefix('acct:'))
+ when 'share'
+ redirect_to share_path(text: uri.query_values['text'])
+ else
+ handle_invalid_uri
end
-
- not_found
end
private
- def check_uri
- not_found if uri.blank?
+ def valid_uri?
+ uri.present? && uri.scheme == EXPECTED_SCHEME
end
def handle_invalid_uri
diff --git a/app/controllers/severed_relationships_controller.rb b/app/controllers/severed_relationships_controller.rb
new file mode 100644
index 0000000000..168e85e3fe
--- /dev/null
+++ b/app/controllers/severed_relationships_controller.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+class SeveredRelationshipsController < ApplicationController
+ layout 'admin'
+
+ before_action :authenticate_user!
+ before_action :set_body_classes
+ before_action :set_cache_headers
+
+ before_action :set_event, only: [:following, :followers]
+
+ def index
+ @events = AccountRelationshipSeveranceEvent.where(account: current_account)
+ end
+
+ def following
+ respond_to do |format|
+ format.csv { send_data following_data, filename: "following-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" }
+ end
+ end
+
+ def followers
+ respond_to do |format|
+ format.csv { send_data followers_data, filename: "followers-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" }
+ end
+ end
+
+ private
+
+ def set_event
+ @event = AccountRelationshipSeveranceEvent.find(params[:id])
+ end
+
+ def following_data
+ CSV.generate(headers: ['Account address', 'Show boosts', 'Notify on new posts', 'Languages'], write_headers: true) do |csv|
+ @event.severed_relationships.active.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow|
+ csv << [acct(follow.target_account), follow.show_reblogs, follow.notify, follow.languages&.join(', ')]
+ end
+ end
+ end
+
+ def followers_data
+ CSV.generate(headers: ['Account address'], write_headers: true) do |csv|
+ @event.severed_relationships.passive.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow|
+ csv << [acct(follow.account)]
+ end
+ end
+ end
+
+ def acct(account)
+ account.local? ? account.local_username_and_domain : account.acct
+ end
+
+ def set_body_classes
+ @body_classes = 'admin'
+ end
+
+ def set_cache_headers
+ response.cache_control.replace(private: true, no_store: true)
+ end
+end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index daa27195e9..233c242e4a 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -28,14 +28,6 @@ module ApplicationHelper
number_to_human(number, **options)
end
- def active_nav_class(*paths)
- paths.any? { |path| current_page?(path) } ? 'active' : ''
- end
-
- def show_landing_strip?
- !user_signed_in? && !single_user_mode?
- end
-
def open_registrations?
Setting.registrations_mode == 'open'
end
@@ -122,7 +114,7 @@ module ApplicationHelper
end
def check_icon
- content_tag(:svg, tag.path('fill-rule': 'evenodd', 'clip-rule': 'evenodd', d: 'M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z'), xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor')
+ inline_svg_tag 'check.svg'
end
def visibility_icon(status)
@@ -214,7 +206,7 @@ module ApplicationHelper
state_params[:moved_to_account] = current_account.moved_to_account
end
- state_params[:owner] = Account.local.without_suspended.where('id > 0').first if single_user_mode?
+ state_params[:owner] = Account.local.without_suspended.without_internal.first if single_user_mode?
json = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(state_params), serializer: InitialStateSerializer).to_json
# rubocop:disable Rails/OutputSafety
diff --git a/app/helpers/branding_helper.rb b/app/helpers/branding_helper.rb
index 2b9c233c23..f72d6df5d9 100644
--- a/app/helpers/branding_helper.rb
+++ b/app/helpers/branding_helper.rb
@@ -21,15 +21,4 @@ module BrandingHelper
def render_logo
image_pack_tag('logo.svg', alt: 'Mastodon', class: 'logo logo--icon')
end
-
- def render_symbol(version = :icon)
- path = case version
- when :icon
- 'logo-symbol-icon.svg'
- when :wordmark
- 'logo-symbol-wordmark.svg'
- end
-
- render(file: Rails.root.join('app', 'javascript', 'images', path)).html_safe # rubocop:disable Rails/OutputSafety
- end
end
diff --git a/app/helpers/context_helper.rb b/app/helpers/context_helper.rb
index 1b79a089bc..412be4f48d 100644
--- a/app/helpers/context_helper.rb
+++ b/app/helpers/context_helper.rb
@@ -25,12 +25,21 @@ module ContextHelper
memorial: { 'toot' => 'http://joinmastodon.org/ns#', 'memorial' => 'toot:memorial' },
voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' },
olm: {
- 'toot' => 'http://joinmastodon.org/ns#', 'Device' => 'toot:Device', 'Ed25519Signature' => 'toot:Ed25519Signature', 'Ed25519Key' => 'toot:Ed25519Key', 'Curve25519Key' => 'toot:Curve25519Key', 'EncryptedMessage' => 'toot:EncryptedMessage', 'publicKeyBase64' => 'toot:publicKeyBase64', 'deviceId' => 'toot:deviceId',
+ 'toot' => 'http://joinmastodon.org/ns#',
+ 'Device' => 'toot:Device',
+ 'Ed25519Signature' => 'toot:Ed25519Signature',
+ 'Ed25519Key' => 'toot:Ed25519Key',
+ 'Curve25519Key' => 'toot:Curve25519Key',
+ 'EncryptedMessage' => 'toot:EncryptedMessage',
+ 'publicKeyBase64' => 'toot:publicKeyBase64',
+ 'deviceId' => 'toot:deviceId',
'claim' => { '@type' => '@id', '@id' => 'toot:claim' },
'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' },
'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' },
'devices' => { '@type' => '@id', '@id' => 'toot:devices' },
- 'messageFranking' => 'toot:messageFranking', 'messageType' => 'toot:messageType', 'cipherText' => 'toot:cipherText'
+ 'messageFranking' => 'toot:messageFranking',
+ 'messageType' => 'toot:messageType',
+ 'cipherText' => 'toot:cipherText',
},
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
}.freeze
diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb
index 87f0f288d3..9e1c0a7db1 100644
--- a/app/helpers/languages_helper.rb
+++ b/app/helpers/languages_helper.rb
@@ -109,6 +109,7 @@ module LanguagesHelper
mn: ['Mongolian', 'Монгол хэл'].freeze,
mr: ['Marathi', 'मराठी'].freeze,
ms: ['Malay', 'Bahasa Melayu'].freeze,
+ 'ms-Arab': ['Jawi Malay', 'بهاس ملايو'].freeze,
mt: ['Maltese', 'Malti'].freeze,
my: ['Burmese', 'ဗမာစာ'].freeze,
na: ['Nauru', 'Ekakairũ Naoero'].freeze,
@@ -127,7 +128,7 @@ module LanguagesHelper
om: ['Oromo', 'Afaan Oromoo'].freeze,
or: ['Oriya', 'ଓଡ଼ିଆ'].freeze,
os: ['Ossetian', 'ирон æвзаг'].freeze,
- pa: ['Panjabi', 'ਪੰਜਾਬੀ'].freeze,
+ pa: ['Punjabi', 'ਪੰਜਾਬੀ'].freeze,
pi: ['Pāli', 'पाऴि'].freeze,
pl: ['Polish', 'Polski'].freeze,
ps: ['Pashto', 'پښتو'].freeze,
@@ -191,15 +192,20 @@ module LanguagesHelper
chr: ['Cherokee', 'ᏣᎳᎩ ᎦᏬᏂᎯᏍᏗ'].freeze,
ckb: ['Sorani (Kurdish)', 'سۆرانی'].freeze,
cnr: ['Montenegrin', 'crnogorski'].freeze,
+ csb: ['Kashubian', 'Kaszëbsczi'].freeze,
jbo: ['Lojban', 'la .lojban.'].freeze,
kab: ['Kabyle', 'Taqbaylit'].freeze,
ldn: ['Láadan', 'Láadan'].freeze,
lfn: ['Lingua Franca Nova', 'lingua franca nova'].freeze,
+ moh: ['Mohawk', 'Kanienʼkéha'].freeze,
+ nds: ['Low German', 'Plattdüütsch'].freeze,
+ pdc: ['Pennsylvania Dutch', 'Pennsilfaani-Deitsch'].freeze,
sco: ['Scots', 'Scots'].freeze,
sma: ['Southern Sami', 'Åarjelsaemien Gïele'].freeze,
smj: ['Lule Sami', 'Julevsámegiella'].freeze,
szl: ['Silesian', 'ślůnsko godka'].freeze,
tok: ['Toki Pona', 'toki pona'].freeze,
+ vai: ['Vai', 'ꕙꔤ'].freeze,
xal: ['Kalmyk', 'Хальмг келн'].freeze,
zba: ['Balaibalan', 'باليبلن'].freeze,
zgh: ['Standard Moroccan Tamazight', 'ⵜⴰⵎⴰⵣⵉⵖⵜ'].freeze,
diff --git a/app/helpers/react_component_helper.rb b/app/helpers/react_component_helper.rb
index ce616e8306..821a6f1e2d 100644
--- a/app/helpers/react_component_helper.rb
+++ b/app/helpers/react_component_helper.rb
@@ -15,9 +15,20 @@ module ReactComponentHelper
div_tag_with_data(data)
end
+ def serialized_media_attachments(media_attachments)
+ media_attachments.map { |attachment| serialized_attachment(attachment) }
+ end
+
private
def div_tag_with_data(data)
content_tag(:div, nil, data: data)
end
+
+ def serialized_attachment(attachment)
+ ActiveModelSerializers::SerializableResource.new(
+ attachment,
+ serializer: REST::MediaAttachmentSerializer
+ ).as_json
+ end
end
diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb
index 286c53d834..ca693a8a78 100644
--- a/app/helpers/statuses_helper.rb
+++ b/app/helpers/statuses_helper.rb
@@ -4,14 +4,6 @@ module StatusesHelper
EMBEDDED_CONTROLLER = 'statuses'
EMBEDDED_ACTION = 'embed'
- def link_to_newer(url)
- link_to t('statuses.show_newer'), url, class: 'load-more load-gap'
- end
-
- def link_to_older(url)
- link_to t('statuses.show_older'), url, class: 'load-more load-gap'
- end
-
def nothing_here(extra_classes = '')
content_tag(:div, class: "nothing-here #{extra_classes}") do
t('accounts.nothing_here')
diff --git a/app/javascript/core/admin.js b/app/javascript/core/admin.js
deleted file mode 100644
index d256d7ec9d..0000000000
--- a/app/javascript/core/admin.js
+++ /dev/null
@@ -1,228 +0,0 @@
-// This file will be loaded on admin pages, regardless of theme.
-
-import 'packs/public-path';
-import Rails from '@rails/ujs';
-
-import ready from '../mastodon/ready';
-
-const setAnnouncementEndsAttributes = (target) => {
- const valid = target?.value && target?.validity?.valid;
- const element = document.querySelector('input[type="datetime-local"]#announcement_ends_at');
- if (valid) {
- element.classList.remove('optional');
- element.required = true;
- element.min = target.value;
- } else {
- element.classList.add('optional');
- element.removeAttribute('required');
- element.removeAttribute('min');
- }
-};
-
-Rails.delegate(document, 'input[type="datetime-local"]#announcement_starts_at', 'change', ({ target }) => {
- setAnnouncementEndsAttributes(target);
-});
-
-const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]';
-
-const showSelectAll = () => {
- const selectAllMatchingElement = document.querySelector('.batch-table__select-all');
- selectAllMatchingElement.classList.add('active');
-};
-
-const hideSelectAll = () => {
- const selectAllMatchingElement = document.querySelector('.batch-table__select-all');
- const hiddenField = document.querySelector('#select_all_matching');
- const selectedMsg = document.querySelector('.batch-table__select-all .selected');
- const notSelectedMsg = document.querySelector('.batch-table__select-all .not-selected');
-
- selectAllMatchingElement.classList.remove('active');
- selectedMsg.classList.remove('active');
- notSelectedMsg.classList.add('active');
- hiddenField.value = '0';
-};
-
-Rails.delegate(document, '#batch_checkbox_all', 'change', ({ target }) => {
- const selectAllMatchingElement = document.querySelector('.batch-table__select-all');
-
- [].forEach.call(document.querySelectorAll(batchCheckboxClassName), (content) => {
- content.checked = target.checked;
- });
-
- if (selectAllMatchingElement) {
- if (target.checked) {
- showSelectAll();
- } else {
- hideSelectAll();
- }
- }
-});
-
-Rails.delegate(document, '.batch-table__select-all button', 'click', () => {
- const hiddenField = document.querySelector('#select_all_matching');
- const active = hiddenField.value === '1';
- const selectedMsg = document.querySelector('.batch-table__select-all .selected');
- const notSelectedMsg = document.querySelector('.batch-table__select-all .not-selected');
-
- if (active) {
- hiddenField.value = '0';
- selectedMsg.classList.remove('active');
- notSelectedMsg.classList.add('active');
- } else {
- hiddenField.value = '1';
- notSelectedMsg.classList.remove('active');
- selectedMsg.classList.add('active');
- }
-});
-
-Rails.delegate(document, batchCheckboxClassName, 'change', () => {
- const checkAllElement = document.querySelector('#batch_checkbox_all');
- const selectAllMatchingElement = document.querySelector('.batch-table__select-all');
-
- if (checkAllElement) {
- checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
- checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
-
- if (selectAllMatchingElement) {
- if (checkAllElement.checked) {
- showSelectAll();
- } else {
- hideSelectAll();
- }
- }
- }
-});
-
-Rails.delegate(document, '.media-spoiler-show-button', 'click', () => {
- [].forEach.call(document.querySelectorAll('button.media-spoiler'), (element) => {
- element.click();
- });
-});
-
-Rails.delegate(document, '.media-spoiler-hide-button', 'click', () => {
- [].forEach.call(document.querySelectorAll('.spoiler-button.spoiler-button--visible button'), (element) => {
- element.click();
- });
-});
-
-Rails.delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => {
- target.form.submit();
-});
-
-const onDomainBlockSeverityChange = (target) => {
- const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media');
- const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports');
-
- if (rejectMediaDiv) {
- rejectMediaDiv.style.display = (target.value === 'suspend') ? 'none' : 'block';
- }
-
- if (rejectReportsDiv) {
- rejectReportsDiv.style.display = (target.value === 'suspend') ? 'none' : 'block';
- }
-};
-
-Rails.delegate(document, '#domain_block_severity', 'change', ({ target }) => onDomainBlockSeverityChange(target));
-
-const onEnableBootstrapTimelineAccountsChange = (target) => {
- const bootstrapTimelineAccountsField = document.querySelector('#form_admin_settings_bootstrap_timeline_accounts');
-
- if (bootstrapTimelineAccountsField) {
- bootstrapTimelineAccountsField.disabled = !target.checked;
- if (target.checked) {
- bootstrapTimelineAccountsField.parentElement.classList.remove('disabled');
- bootstrapTimelineAccountsField.parentElement.parentElement.classList.remove('disabled');
- } else {
- bootstrapTimelineAccountsField.parentElement.classList.add('disabled');
- bootstrapTimelineAccountsField.parentElement.parentElement.classList.add('disabled');
- }
- }
-};
-
-Rails.delegate(document, '#form_admin_settings_enable_bootstrap_timeline_accounts', 'change', ({ target }) => onEnableBootstrapTimelineAccountsChange(target));
-
-const onChangeRegistrationMode = (target) => {
- const enabled = target.value === 'approved';
-
- [].forEach.call(document.querySelectorAll('#form_admin_settings_require_invite_text'), (input) => {
- input.disabled = !enabled;
- if (enabled) {
- let element = input;
- do {
- element.classList.remove('disabled');
- element = element.parentElement;
- } while (element && !element.classList.contains('fields-group'));
- } else {
- let element = input;
- do {
- element.classList.add('disabled');
- element = element.parentElement;
- } while (element && !element.classList.contains('fields-group'));
- }
- });
-};
-
-const convertUTCDateTimeToLocal = (value) => {
- const date = new Date(value + 'Z');
- const twoChars = (x) => (x.toString().padStart(2, '0'));
- return `${date.getFullYear()}-${twoChars(date.getMonth()+1)}-${twoChars(date.getDate())}T${twoChars(date.getHours())}:${twoChars(date.getMinutes())}`;
-};
-
-const convertLocalDatetimeToUTC = (value) => {
- const re = /^([0-9]{4,})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})/;
- const match = re.exec(value);
- const date = new Date(match[1], match[2] - 1, match[3], match[4], match[5]);
- const fullISO8601 = date.toISOString();
- return fullISO8601.slice(0, fullISO8601.indexOf('T') + 6);
-};
-
-Rails.delegate(document, '#form_admin_settings_registrations_mode', 'change', ({ target }) => onChangeRegistrationMode(target));
-
-ready(() => {
- const domainBlockSeverityInput = document.getElementById('domain_block_severity');
- if (domainBlockSeverityInput) onDomainBlockSeverityChange(domainBlockSeverityInput);
-
- const enableBootstrapTimelineAccounts = document.getElementById('form_admin_settings_enable_bootstrap_timeline_accounts');
- if (enableBootstrapTimelineAccounts) onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts);
-
- const registrationMode = document.getElementById('form_admin_settings_registrations_mode');
- if (registrationMode) onChangeRegistrationMode(registrationMode);
-
- const checkAllElement = document.querySelector('#batch_checkbox_all');
- if (checkAllElement) {
- checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
- checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked);
- }
-
- document.querySelector('a#add-instance-button')?.addEventListener('click', (e) => {
- const domain = document.querySelector('input[type="text"]#by_domain')?.value;
-
- if (domain) {
- const url = new URL(event.target.href);
- url.searchParams.set('_domain', domain);
- e.target.href = url;
- }
- });
-
- [].forEach.call(document.querySelectorAll('input[type="datetime-local"]'), element => {
- if (element.value) {
- element.value = convertUTCDateTimeToLocal(element.value);
- }
- if (element.placeholder) {
- element.placeholder = convertUTCDateTimeToLocal(element.placeholder);
- }
- });
-
- Rails.delegate(document, 'form', 'submit', ({ target }) => {
- [].forEach.call(target.querySelectorAll('input[type="datetime-local"]'), element => {
- if (element.value && element.validity.valid) {
- element.value = convertLocalDatetimeToUTC(element.value);
- }
- });
- });
-
- const announcementStartsAt = document.querySelector('input[type="datetime-local"]#announcement_starts_at');
- if (announcementStartsAt) {
- setAnnouncementEndsAttributes(announcementStartsAt);
- }
-});
diff --git a/app/javascript/core/admin.ts b/app/javascript/core/admin.ts
new file mode 100644
index 0000000000..0642affef0
--- /dev/null
+++ b/app/javascript/core/admin.ts
@@ -0,0 +1,340 @@
+// This file will be loaded on admin pages, regardless of theme.
+
+import 'packs/public-path';
+
+import Rails from '@rails/ujs';
+
+import ready from '../mastodon/ready';
+
+const setAnnouncementEndsAttributes = (target: HTMLInputElement) => {
+ const valid = target.value && target.validity.valid;
+ const element = document.querySelector(
+ 'input[type="datetime-local"]#announcement_ends_at',
+ );
+
+ if (!element) return;
+
+ if (valid) {
+ element.classList.remove('optional');
+ element.required = true;
+ element.min = target.value;
+ } else {
+ element.classList.add('optional');
+ element.removeAttribute('required');
+ element.removeAttribute('min');
+ }
+};
+
+Rails.delegate(
+ document,
+ 'input[type="datetime-local"]#announcement_starts_at',
+ 'change',
+ ({ target }) => {
+ if (target instanceof HTMLInputElement)
+ setAnnouncementEndsAttributes(target);
+ },
+);
+
+const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]';
+
+const showSelectAll = () => {
+ const selectAllMatchingElement = document.querySelector(
+ '.batch-table__select-all',
+ );
+ selectAllMatchingElement?.classList.add('active');
+};
+
+const hideSelectAll = () => {
+ const selectAllMatchingElement = document.querySelector(
+ '.batch-table__select-all',
+ );
+ const hiddenField = document.querySelector(
+ 'input#select_all_matching',
+ );
+ const selectedMsg = document.querySelector(
+ '.batch-table__select-all .selected',
+ );
+ const notSelectedMsg = document.querySelector(
+ '.batch-table__select-all .not-selected',
+ );
+
+ selectAllMatchingElement?.classList.remove('active');
+ selectedMsg?.classList.remove('active');
+ notSelectedMsg?.classList.add('active');
+ if (hiddenField) hiddenField.value = '0';
+};
+
+Rails.delegate(document, '#batch_checkbox_all', 'change', ({ target }) => {
+ if (!(target instanceof HTMLInputElement)) return;
+
+ const selectAllMatchingElement = document.querySelector(
+ '.batch-table__select-all',
+ );
+
+ document
+ .querySelectorAll(batchCheckboxClassName)
+ .forEach((content) => {
+ content.checked = target.checked;
+ });
+
+ if (selectAllMatchingElement) {
+ if (target.checked) {
+ showSelectAll();
+ } else {
+ hideSelectAll();
+ }
+ }
+});
+
+Rails.delegate(document, '.batch-table__select-all button', 'click', () => {
+ const hiddenField = document.querySelector(
+ '#select_all_matching',
+ );
+
+ if (!hiddenField) return;
+
+ const active = hiddenField.value === '1';
+ const selectedMsg = document.querySelector(
+ '.batch-table__select-all .selected',
+ );
+ const notSelectedMsg = document.querySelector(
+ '.batch-table__select-all .not-selected',
+ );
+
+ if (!selectedMsg || !notSelectedMsg) return;
+
+ if (active) {
+ hiddenField.value = '0';
+ selectedMsg.classList.remove('active');
+ notSelectedMsg.classList.add('active');
+ } else {
+ hiddenField.value = '1';
+ notSelectedMsg.classList.remove('active');
+ selectedMsg.classList.add('active');
+ }
+});
+
+Rails.delegate(document, batchCheckboxClassName, 'change', () => {
+ const checkAllElement = document.querySelector(
+ 'input#batch_checkbox_all',
+ );
+ const selectAllMatchingElement = document.querySelector(
+ '.batch-table__select-all',
+ );
+
+ if (checkAllElement) {
+ const allCheckboxes = Array.from(
+ document.querySelectorAll(batchCheckboxClassName),
+ );
+ checkAllElement.checked = allCheckboxes.every((content) => content.checked);
+ checkAllElement.indeterminate =
+ !checkAllElement.checked &&
+ allCheckboxes.some((content) => content.checked);
+
+ if (selectAllMatchingElement) {
+ if (checkAllElement.checked) {
+ showSelectAll();
+ } else {
+ hideSelectAll();
+ }
+ }
+ }
+});
+
+Rails.delegate(
+ document,
+ '.filter-subset--with-select select',
+ 'change',
+ ({ target }) => {
+ if (target instanceof HTMLSelectElement) target.form?.submit();
+ },
+);
+
+const onDomainBlockSeverityChange = (target: HTMLSelectElement) => {
+ const rejectMediaDiv = document.querySelector(
+ '.input.with_label.domain_block_reject_media',
+ );
+ const rejectReportsDiv = document.querySelector(
+ '.input.with_label.domain_block_reject_reports',
+ );
+
+ if (rejectMediaDiv && rejectMediaDiv instanceof HTMLElement) {
+ rejectMediaDiv.style.display =
+ target.value === 'suspend' ? 'none' : 'block';
+ }
+
+ if (rejectReportsDiv && rejectReportsDiv instanceof HTMLElement) {
+ rejectReportsDiv.style.display =
+ target.value === 'suspend' ? 'none' : 'block';
+ }
+};
+
+Rails.delegate(document, '#domain_block_severity', 'change', ({ target }) => {
+ if (target instanceof HTMLSelectElement) onDomainBlockSeverityChange(target);
+});
+
+const onEnableBootstrapTimelineAccountsChange = (target: HTMLInputElement) => {
+ const bootstrapTimelineAccountsField =
+ document.querySelector(
+ '#form_admin_settings_bootstrap_timeline_accounts',
+ );
+
+ if (bootstrapTimelineAccountsField) {
+ bootstrapTimelineAccountsField.disabled = !target.checked;
+ if (target.checked) {
+ bootstrapTimelineAccountsField.parentElement?.classList.remove(
+ 'disabled',
+ );
+ bootstrapTimelineAccountsField.parentElement?.parentElement?.classList.remove(
+ 'disabled',
+ );
+ } else {
+ bootstrapTimelineAccountsField.parentElement?.classList.add('disabled');
+ bootstrapTimelineAccountsField.parentElement?.parentElement?.classList.add(
+ 'disabled',
+ );
+ }
+ }
+};
+
+Rails.delegate(
+ document,
+ '#form_admin_settings_enable_bootstrap_timeline_accounts',
+ 'change',
+ ({ target }) => {
+ if (target instanceof HTMLInputElement)
+ onEnableBootstrapTimelineAccountsChange(target);
+ },
+);
+
+const onChangeRegistrationMode = (target: HTMLSelectElement) => {
+ const enabled = target.value === 'approved';
+
+ document
+ .querySelectorAll(
+ '.form_admin_settings_registrations_mode .warning-hint',
+ )
+ .forEach((warning_hint) => {
+ warning_hint.style.display = target.value === 'open' ? 'inline' : 'none';
+ });
+
+ document
+ .querySelectorAll(
+ 'input#form_admin_settings_require_invite_text',
+ )
+ .forEach((input) => {
+ input.disabled = !enabled;
+ if (enabled) {
+ let element: HTMLElement | null = input;
+ do {
+ element.classList.remove('disabled');
+ element = element.parentElement;
+ } while (element && !element.classList.contains('fields-group'));
+ } else {
+ let element: HTMLElement | null = input;
+ do {
+ element.classList.add('disabled');
+ element = element.parentElement;
+ } while (element && !element.classList.contains('fields-group'));
+ }
+ });
+};
+
+const convertUTCDateTimeToLocal = (value: string) => {
+ const date = new Date(value + 'Z');
+ const twoChars = (x: number) => x.toString().padStart(2, '0');
+ return `${date.getFullYear()}-${twoChars(date.getMonth() + 1)}-${twoChars(date.getDate())}T${twoChars(date.getHours())}:${twoChars(date.getMinutes())}`;
+};
+
+function convertLocalDatetimeToUTC(value: string) {
+ const date = new Date(value);
+ const fullISO8601 = date.toISOString();
+ return fullISO8601.slice(0, fullISO8601.indexOf('T') + 6);
+}
+
+Rails.delegate(
+ document,
+ '#form_admin_settings_registrations_mode',
+ 'change',
+ ({ target }) => {
+ if (target instanceof HTMLSelectElement) onChangeRegistrationMode(target);
+ },
+);
+
+ready(() => {
+ const domainBlockSeveritySelect = document.querySelector(
+ 'select#domain_block_severity',
+ );
+ if (domainBlockSeveritySelect)
+ onDomainBlockSeverityChange(domainBlockSeveritySelect);
+
+ const enableBootstrapTimelineAccounts =
+ document.querySelector(
+ 'input#form_admin_settings_enable_bootstrap_timeline_accounts',
+ );
+ if (enableBootstrapTimelineAccounts)
+ onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts);
+
+ const registrationMode = document.querySelector(
+ 'select#form_admin_settings_registrations_mode',
+ );
+ if (registrationMode) onChangeRegistrationMode(registrationMode);
+
+ const checkAllElement = document.querySelector(
+ 'input#batch_checkbox_all',
+ );
+ if (checkAllElement) {
+ const allCheckboxes = Array.from(
+ document.querySelectorAll(batchCheckboxClassName),
+ );
+ checkAllElement.checked = allCheckboxes.every((content) => content.checked);
+ checkAllElement.indeterminate =
+ !checkAllElement.checked &&
+ allCheckboxes.some((content) => content.checked);
+ }
+
+ document
+ .querySelector('a#add-instance-button')
+ ?.addEventListener('click', (e) => {
+ const domain = document.querySelector(
+ 'input[type="text"]#by_domain',
+ )?.value;
+
+ if (domain && e.target instanceof HTMLAnchorElement) {
+ const url = new URL(e.target.href);
+ url.searchParams.set('_domain', domain);
+ e.target.href = url.toString();
+ }
+ });
+
+ document
+ .querySelectorAll('input[type="datetime-local"]')
+ .forEach((element) => {
+ if (element.value) {
+ element.value = convertUTCDateTimeToLocal(element.value);
+ }
+ if (element.placeholder) {
+ element.placeholder = convertUTCDateTimeToLocal(element.placeholder);
+ }
+ });
+
+ Rails.delegate(document, 'form', 'submit', ({ target }) => {
+ if (target instanceof HTMLFormElement)
+ target
+ .querySelectorAll('input[type="datetime-local"]')
+ .forEach((element) => {
+ if (element.value && element.validity.valid) {
+ element.value = convertLocalDatetimeToUTC(element.value);
+ }
+ });
+ });
+
+ const announcementStartsAt = document.querySelector(
+ 'input[type="datetime-local"]#announcement_starts_at',
+ );
+ if (announcementStartsAt) {
+ setAnnouncementEndsAttributes(announcementStartsAt);
+ }
+}).catch((reason) => {
+ throw reason;
+});
diff --git a/app/javascript/core/embed.js b/app/javascript/core/embed.js
deleted file mode 100644
index d1e8f6b108..0000000000
--- a/app/javascript/core/embed.js
+++ /dev/null
@@ -1,25 +0,0 @@
-// This file will be loaded on embed pages, regardless of theme.
-
-import 'packs/public-path';
-
-window.addEventListener('message', e => {
- const data = e.data || {};
-
- if (!window.parent || data.type !== 'setHeight') {
- return;
- }
-
- function setEmbedHeight () {
- window.parent.postMessage({
- type: 'setHeight',
- id: data.id,
- height: document.getElementsByTagName('html')[0].scrollHeight,
- }, '*');
- }
-
- if (['interactive', 'complete'].includes(document.readyState)) {
- setEmbedHeight();
- } else {
- document.addEventListener('DOMContentLoaded', setEmbedHeight);
- }
-});
diff --git a/app/javascript/core/embed.ts b/app/javascript/core/embed.ts
new file mode 100644
index 0000000000..6766cd7788
--- /dev/null
+++ b/app/javascript/core/embed.ts
@@ -0,0 +1,41 @@
+// This file will be loaded on embed pages, regardless of theme.
+
+import 'packs/public-path';
+import ready from '../mastodon/ready';
+
+interface SetHeightMessage {
+ type: 'setHeight';
+ id: string;
+ height: number;
+}
+
+function isSetHeightMessage(data: unknown): data is SetHeightMessage {
+ if (
+ data &&
+ typeof data === 'object' &&
+ 'type' in data &&
+ data.type === 'setHeight'
+ )
+ return true;
+ else return false;
+}
+
+window.addEventListener('message', (e) => {
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typings are not correct, it can be null in very rare cases
+ if (!e.data || !isSetHeightMessage(e.data) || !window.parent) return;
+
+ const data = e.data;
+
+ ready(() => {
+ window.parent.postMessage(
+ {
+ type: 'setHeight',
+ id: data.id,
+ height: document.getElementsByTagName('html')[0].scrollHeight,
+ },
+ '*',
+ );
+ }).catch((e) => {
+ console.error('Error in setHeightMessage postMessage', e);
+ });
+});
diff --git a/app/javascript/core/settings.js b/app/javascript/core/settings.js
deleted file mode 100644
index 23367d2d31..0000000000
--- a/app/javascript/core/settings.js
+++ /dev/null
@@ -1,44 +0,0 @@
-// This file will be loaded on settings pages, regardless of theme.
-
-import 'packs/public-path';
-import Rails from '@rails/ujs';
-
-Rails.delegate(document, '#edit_profile input[type=file]', 'change', ({ target }) => {
- const avatar = document.getElementById(target.id + '-preview');
- const [file] = target.files || [];
- const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
-
- avatar.src = url;
-});
-
-Rails.delegate(document, '.input-copy input', 'click', ({ target }) => {
- target.focus();
- target.select();
- target.setSelectionRange(0, target.value.length);
-});
-
-Rails.delegate(document, '.input-copy button', 'click', ({ target }) => {
- const input = target.parentNode.querySelector('.input-copy__wrapper input');
-
- const oldReadOnly = input.readonly;
-
- input.readonly = false;
- input.focus();
- input.select();
- input.setSelectionRange(0, input.value.length);
-
- try {
- if (document.execCommand('copy')) {
- input.blur();
- target.parentNode.classList.add('copied');
-
- setTimeout(() => {
- target.parentNode.classList.remove('copied');
- }, 700);
- }
- } catch (err) {
- console.error(err);
- }
-
- input.readonly = oldReadOnly;
-});
diff --git a/app/javascript/core/settings.ts b/app/javascript/core/settings.ts
new file mode 100644
index 0000000000..ea6a99ec80
--- /dev/null
+++ b/app/javascript/core/settings.ts
@@ -0,0 +1,70 @@
+// This file will be loaded on settings pages, regardless of theme.
+
+import 'packs/public-path';
+import Rails from '@rails/ujs';
+
+Rails.delegate(
+ document,
+ '#edit_profile input[type=file]',
+ 'change',
+ ({ target }) => {
+ if (!(target instanceof HTMLInputElement)) return;
+
+ const avatar = document.querySelector(
+ `img#${target.id}-preview`,
+ );
+
+ if (!avatar) return;
+
+ let file: File | undefined;
+ if (target.files) file = target.files[0];
+
+ const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc;
+
+ if (url) avatar.src = url;
+ },
+);
+
+Rails.delegate(document, '.input-copy input', 'click', ({ target }) => {
+ if (!(target instanceof HTMLInputElement)) return;
+
+ target.focus();
+ target.select();
+ target.setSelectionRange(0, target.value.length);
+});
+
+Rails.delegate(document, '.input-copy button', 'click', ({ target }) => {
+ if (!(target instanceof HTMLButtonElement)) return;
+
+ const input = target.parentNode?.querySelector(
+ '.input-copy__wrapper input',
+ );
+
+ if (!input) return;
+
+ const oldReadOnly = input.readOnly;
+
+ input.readOnly = false;
+ input.focus();
+ input.select();
+ input.setSelectionRange(0, input.value.length);
+
+ try {
+ if (document.execCommand('copy')) {
+ input.blur();
+
+ const parent = target.parentElement;
+
+ if (!parent) return;
+ parent.classList.add('copied');
+
+ setTimeout(() => {
+ parent.classList.remove('copied');
+ }, 700);
+ }
+ } catch (err) {
+ console.error(err);
+ }
+
+ input.readOnly = oldReadOnly;
+});
diff --git a/app/javascript/core/theme.yml b/app/javascript/core/theme.yml
index f6f653c0a9..12c23e2035 100644
--- a/app/javascript/core/theme.yml
+++ b/app/javascript/core/theme.yml
@@ -2,12 +2,12 @@
# theme.
pack:
about:
- admin: admin.js
+ admin: admin.ts
auth: auth.js
common:
filename: common.js
stylesheet: true
- embed: embed.js
+ embed: embed.ts
error:
home:
inert:
@@ -18,7 +18,7 @@ pack:
stylesheet: true
modal:
public:
- settings: settings.js
+ settings: settings.ts
sign_up:
share:
remote_interaction_helper: remote_interaction_helper.ts
diff --git a/app/javascript/flavours/glitch/actions/accounts.js b/app/javascript/flavours/glitch/actions/accounts.js
index af10af9fe9..bb26035e97 100644
--- a/app/javascript/flavours/glitch/actions/accounts.js
+++ b/app/javascript/flavours/glitch/actions/accounts.js
@@ -66,11 +66,9 @@ export const FOLLOW_REQUESTS_EXPAND_SUCCESS = 'FOLLOW_REQUESTS_EXPAND_SUCCESS';
export const FOLLOW_REQUESTS_EXPAND_FAIL = 'FOLLOW_REQUESTS_EXPAND_FAIL';
export const FOLLOW_REQUEST_AUTHORIZE_REQUEST = 'FOLLOW_REQUEST_AUTHORIZE_REQUEST';
-export const FOLLOW_REQUEST_AUTHORIZE_SUCCESS = 'FOLLOW_REQUEST_AUTHORIZE_SUCCESS';
export const FOLLOW_REQUEST_AUTHORIZE_FAIL = 'FOLLOW_REQUEST_AUTHORIZE_FAIL';
export const FOLLOW_REQUEST_REJECT_REQUEST = 'FOLLOW_REQUEST_REJECT_REQUEST';
-export const FOLLOW_REQUEST_REJECT_SUCCESS = 'FOLLOW_REQUEST_REJECT_SUCCESS';
export const FOLLOW_REQUEST_REJECT_FAIL = 'FOLLOW_REQUEST_REJECT_FAIL';
export const PINNED_ACCOUNTS_FETCH_REQUEST = 'PINNED_ACCOUNTS_FETCH_REQUEST';
@@ -93,11 +91,6 @@ export * from './accounts_typed';
export function fetchAccount(id) {
return (dispatch, getState) => {
dispatch(fetchRelationships([id]));
-
- if (getState().getIn(['accounts', id], null) !== null) {
- return;
- }
-
dispatch(fetchAccountRequest(id));
api(getState).get(`/api/v1/accounts/${id}`).then(response => {
diff --git a/app/javascript/flavours/glitch/actions/blocks.js b/app/javascript/flavours/glitch/actions/blocks.js
index e293657ad3..54296d0905 100644
--- a/app/javascript/flavours/glitch/actions/blocks.js
+++ b/app/javascript/flavours/glitch/actions/blocks.js
@@ -12,8 +12,6 @@ export const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST';
export const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS';
export const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL';
-export const BLOCKS_INIT_MODAL = 'BLOCKS_INIT_MODAL';
-
export function fetchBlocks() {
return (dispatch, getState) => {
dispatch(fetchBlocksRequest());
@@ -90,11 +88,12 @@ export function expandBlocksFail(error) {
export function initBlockModal(account) {
return dispatch => {
- dispatch({
- type: BLOCKS_INIT_MODAL,
- account,
- });
-
- dispatch(openModal({ modalType: 'BLOCK' }));
+ dispatch(openModal({
+ modalType: 'BLOCK',
+ modalProps: {
+ accountId: account.get('id'),
+ acct: account.get('acct'),
+ },
+ }));
};
}
diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js
index 07f60b9270..1dca94ae68 100644
--- a/app/javascript/flavours/glitch/actions/compose.js
+++ b/app/javascript/flavours/glitch/actions/compose.js
@@ -21,7 +21,6 @@ let fetchComposeSuggestionsAccountsController;
let fetchComposeSuggestionsTagsController;
export const COMPOSE_CHANGE = 'COMPOSE_CHANGE';
-export const COMPOSE_CYCLE_ELEFRIEND = 'COMPOSE_CYCLE_ELEFRIEND';
export const COMPOSE_SUBMIT_REQUEST = 'COMPOSE_SUBMIT_REQUEST';
export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS';
export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL';
@@ -59,7 +58,7 @@ export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
-export const COMPOSE_LISTABILITY_CHANGE = 'COMPOSE_LISTABILITY_CHANGE';
+export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
export const COMPOSE_CONTENT_TYPE_CHANGE = 'COMPOSE_CONTENT_TYPE_CHANGE';
export const COMPOSE_LANGUAGE_CHANGE = 'COMPOSE_LANGUAGE_CHANGE';
@@ -82,6 +81,7 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL';
export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION';
export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS';
+export const COMPOSE_CHANGE_MEDIA_ORDER = 'COMPOSE_CHANGE_MEDIA_ORDER';
export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
export const COMPOSE_FOCUS = 'COMPOSE_FOCUS';
@@ -117,12 +117,6 @@ export function changeCompose(text) {
};
}
-export function cycleElefriendCompose() {
- return {
- type: COMPOSE_CYCLE_ELEFRIEND,
- };
-}
-
export function replyCompose(status, routerHistory) {
return (dispatch, getState) => {
const prependCWRe = getState().getIn(['local_settings', 'prepend_cw_re']);
@@ -148,13 +142,13 @@ export function resetCompose() {
};
}
-export const focusCompose = (routerHistory, defaultText) => dispatch => {
+export const focusCompose = (routerHistory, defaultText) => (dispatch, getState) => {
dispatch({
type: COMPOSE_FOCUS,
defaultText,
});
- ensureComposeIsVisible(routerHistory);
+ ensureComposeIsVisible(getState, routerHistory);
};
export function mentionCompose(account, routerHistory) {
@@ -179,7 +173,7 @@ export function directCompose(account, routerHistory) {
};
}
-export function submitCompose(routerHistory) {
+export function submitCompose(routerHistory, overridePrivacy = null) {
return function (dispatch, getState) {
let status = getState().getIn(['compose', 'text'], '');
const media = getState().getIn(['compose', 'media_attachments']);
@@ -228,7 +222,7 @@ export function submitCompose(routerHistory) {
media_attributes,
sensitive: getState().getIn(['compose', 'sensitive']) || (spoilerText.length > 0 && media.size !== 0),
spoiler_text: spoilerText,
- visibility: getState().getIn(['compose', 'privacy']),
+ visibility: overridePrivacy || getState().getIn(['compose', 'privacy']),
poll: getState().getIn(['compose', 'poll'], null),
language: getState().getIn(['compose', 'language']),
},
@@ -246,11 +240,6 @@ export function submitCompose(routerHistory) {
dispatch(insertIntoTagHistory(response.data.tags, status));
dispatch(submitComposeSuccess({ ...response.data }));
- // If the response has no data then we can't do anything else.
- if (!response.data) {
- return;
- }
-
// To make the app more responsive, immediately push the status
// into the columns
const insertIfOnline = timelineId => {
@@ -278,12 +267,14 @@ export function submitCompose(routerHistory) {
insertIfOnline('direct');
}
- dispatch(showAlert({
- message: statusId === null ? messages.published : messages.saved,
- action: messages.open,
- dismissAfter: 10000,
- onClick: () => routerHistory.push(`/@${response.data.account.username}/${response.data.id}`),
- }));
+ if (getState().getIn(['local_settings', 'show_published_toast'])) {
+ dispatch(showAlert({
+ message: statusId === null ? messages.published : messages.saved,
+ action: messages.open,
+ dismissAfter: 10000,
+ onClick: () => routerHistory.push(`/@${response.data.account.username}/${response.data.id}`),
+ }));
+ }
}).catch(function (error) {
dispatch(submitComposeFail(error));
});
@@ -660,15 +651,19 @@ export const readyComposeSuggestionsTags = (token, tags) => ({
export function selectComposeSuggestion(position, token, suggestion, path) {
return (dispatch, getState) => {
- let completion;
+ let completion, startPosition;
+
if (suggestion.type === 'emoji') {
- completion = suggestion.native || suggestion.colons;
+ completion = suggestion.native || suggestion.colons;
+ startPosition = position - 1;
dispatch(useEmoji(suggestion));
} else if (suggestion.type === 'hashtag') {
- completion = `#${suggestion.name}`;
+ completion = `#${suggestion.name}`;
+ startPosition = position - 1;
} else if (suggestion.type === 'account') {
- completion = '@' + getState().getIn(['accounts', suggestion.id, 'acct']);
+ completion = getState().getIn(['accounts', suggestion.id, 'acct']);
+ startPosition = position;
}
// We don't want to replace hashtags that vary only in case due to accessibility, but we need to fire off an event so that
@@ -676,7 +671,7 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
if (suggestion.type !== 'hashtag' || token.slice(1).localeCompare(suggestion.name, undefined, { sensitivity: 'accent' }) !== 0) {
dispatch({
type: COMPOSE_SUGGESTION_SELECT,
- position,
+ position: startPosition,
token,
completion,
path,
@@ -684,7 +679,7 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
} else {
dispatch({
type: COMPOSE_SUGGESTION_IGNORE,
- position,
+ position: startPosition,
token,
completion,
path,
@@ -786,18 +781,26 @@ export function changeComposeVisibility(value) {
};
}
-export function changeComposeContentType(value) {
- return {
- type: COMPOSE_CONTENT_TYPE_CHANGE,
- value,
- };
-}
-
-export function insertEmojiCompose(position, emoji) {
+export function insertEmojiCompose(position, emoji, needsSpace) {
return {
type: COMPOSE_EMOJI_INSERT,
position,
emoji,
+ needsSpace,
+ };
+}
+
+export function changeComposing(value) {
+ return {
+ type: COMPOSE_COMPOSING_CHANGE,
+ value,
+ };
+}
+
+export function changeComposeContentType(value) {
+ return {
+ type: COMPOSE_CONTENT_TYPE_CHANGE,
+ value,
};
}
@@ -820,11 +823,12 @@ export function addPollOption(title) {
};
}
-export function changePollOption(index, title) {
+export function changePollOption(index, title, maxOptions) {
return {
type: COMPOSE_POLL_OPTION_CHANGE,
index,
title,
+ maxOptions,
};
}
@@ -842,3 +846,9 @@ export function changePollSettings(expiresIn, isMultiple) {
isMultiple,
};
}
+
+export const changeMediaOrder = (a, b) => ({
+ type: COMPOSE_CHANGE_MEDIA_ORDER,
+ a,
+ b,
+});
diff --git a/app/javascript/flavours/glitch/actions/domain_blocks.js b/app/javascript/flavours/glitch/actions/domain_blocks.js
index 718002613f..55c0a6ce9d 100644
--- a/app/javascript/flavours/glitch/actions/domain_blocks.js
+++ b/app/javascript/flavours/glitch/actions/domain_blocks.js
@@ -1,6 +1,8 @@
import api, { getLinks } from '../api';
import { blockDomainSuccess, unblockDomainSuccess } from "./domain_blocks_typed";
+import { openModal } from './modal';
+
export * from "./domain_blocks_typed";
@@ -150,3 +152,12 @@ export function expandDomainBlocksFail(error) {
error,
};
}
+
+export const initDomainBlockModal = account => dispatch => dispatch(openModal({
+ modalType: 'DOMAIN_BLOCK',
+ modalProps: {
+ domain: account.get('acct').split('@')[1],
+ acct: account.get('acct'),
+ accountId: account.get('id'),
+ },
+}));
diff --git a/app/javascript/flavours/glitch/actions/mutes.js b/app/javascript/flavours/glitch/actions/mutes.js
index fb041078b8..99c113f414 100644
--- a/app/javascript/flavours/glitch/actions/mutes.js
+++ b/app/javascript/flavours/glitch/actions/mutes.js
@@ -12,10 +12,6 @@ export const MUTES_EXPAND_REQUEST = 'MUTES_EXPAND_REQUEST';
export const MUTES_EXPAND_SUCCESS = 'MUTES_EXPAND_SUCCESS';
export const MUTES_EXPAND_FAIL = 'MUTES_EXPAND_FAIL';
-export const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL';
-export const MUTES_TOGGLE_HIDE_NOTIFICATIONS = 'MUTES_TOGGLE_HIDE_NOTIFICATIONS';
-export const MUTES_CHANGE_DURATION = 'MUTES_CHANGE_DURATION';
-
export function fetchMutes() {
return (dispatch, getState) => {
dispatch(fetchMutesRequest());
@@ -92,26 +88,12 @@ export function expandMutesFail(error) {
export function initMuteModal(account) {
return dispatch => {
- dispatch({
- type: MUTES_INIT_MODAL,
- account,
- });
-
- dispatch(openModal({ modalType: 'MUTE' }));
- };
-}
-
-export function toggleHideNotifications() {
- return dispatch => {
- dispatch({ type: MUTES_TOGGLE_HIDE_NOTIFICATIONS });
- };
-}
-
-export function changeMuteDuration(duration) {
- return dispatch => {
- dispatch({
- type: MUTES_CHANGE_DURATION,
- duration,
- });
+ dispatch(openModal({
+ modalType: 'MUTE',
+ modalProps: {
+ accountId: account.get('id'),
+ acct: account.get('acct'),
+ },
+ }));
};
}
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js
index 6a0bf01b90..ff50e8f7d0 100644
--- a/app/javascript/flavours/glitch/actions/notifications.js
+++ b/app/javascript/flavours/glitch/actions/notifications.js
@@ -57,6 +57,38 @@ export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
+export const NOTIFICATION_POLICY_FETCH_REQUEST = 'NOTIFICATION_POLICY_FETCH_REQUEST';
+export const NOTIFICATION_POLICY_FETCH_SUCCESS = 'NOTIFICATION_POLICY_FETCH_SUCCESS';
+export const NOTIFICATION_POLICY_FETCH_FAIL = 'NOTIFICATION_POLICY_FETCH_FAIL';
+
+export const NOTIFICATION_REQUESTS_FETCH_REQUEST = 'NOTIFICATION_REQUESTS_FETCH_REQUEST';
+export const NOTIFICATION_REQUESTS_FETCH_SUCCESS = 'NOTIFICATION_REQUESTS_FETCH_SUCCESS';
+export const NOTIFICATION_REQUESTS_FETCH_FAIL = 'NOTIFICATION_REQUESTS_FETCH_FAIL';
+
+export const NOTIFICATION_REQUESTS_EXPAND_REQUEST = 'NOTIFICATION_REQUESTS_EXPAND_REQUEST';
+export const NOTIFICATION_REQUESTS_EXPAND_SUCCESS = 'NOTIFICATION_REQUESTS_EXPAND_SUCCESS';
+export const NOTIFICATION_REQUESTS_EXPAND_FAIL = 'NOTIFICATION_REQUESTS_EXPAND_FAIL';
+
+export const NOTIFICATION_REQUEST_FETCH_REQUEST = 'NOTIFICATION_REQUEST_FETCH_REQUEST';
+export const NOTIFICATION_REQUEST_FETCH_SUCCESS = 'NOTIFICATION_REQUEST_FETCH_SUCCESS';
+export const NOTIFICATION_REQUEST_FETCH_FAIL = 'NOTIFICATION_REQUEST_FETCH_FAIL';
+
+export const NOTIFICATION_REQUEST_ACCEPT_REQUEST = 'NOTIFICATION_REQUEST_ACCEPT_REQUEST';
+export const NOTIFICATION_REQUEST_ACCEPT_SUCCESS = 'NOTIFICATION_REQUEST_ACCEPT_SUCCESS';
+export const NOTIFICATION_REQUEST_ACCEPT_FAIL = 'NOTIFICATION_REQUEST_ACCEPT_FAIL';
+
+export const NOTIFICATION_REQUEST_DISMISS_REQUEST = 'NOTIFICATION_REQUEST_DISMISS_REQUEST';
+export const NOTIFICATION_REQUEST_DISMISS_SUCCESS = 'NOTIFICATION_REQUEST_DISMISS_SUCCESS';
+export const NOTIFICATION_REQUEST_DISMISS_FAIL = 'NOTIFICATION_REQUEST_DISMISS_FAIL';
+
+export const NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST = 'NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST';
+export const NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS = 'NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS';
+export const NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL = 'NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL';
+
+export const NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST';
+export const NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS';
+export const NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL';
+
defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
});
@@ -402,3 +434,270 @@ export function setBrowserPermission (value) {
value,
};
}
+
+export const fetchNotificationPolicy = () => (dispatch, getState) => {
+ dispatch(fetchNotificationPolicyRequest());
+
+ api(getState).get('/api/v1/notifications/policy').then(({ data }) => {
+ dispatch(fetchNotificationPolicySuccess(data));
+ }).catch(err => {
+ dispatch(fetchNotificationPolicyFail(err));
+ });
+};
+
+export const fetchNotificationPolicyRequest = () => ({
+ type: NOTIFICATION_POLICY_FETCH_REQUEST,
+});
+
+export const fetchNotificationPolicySuccess = policy => ({
+ type: NOTIFICATION_POLICY_FETCH_SUCCESS,
+ policy,
+});
+
+export const fetchNotificationPolicyFail = error => ({
+ type: NOTIFICATION_POLICY_FETCH_FAIL,
+ error,
+});
+
+export const updateNotificationsPolicy = params => (dispatch, getState) => {
+ dispatch(fetchNotificationPolicyRequest());
+
+ api(getState).put('/api/v1/notifications/policy', params).then(({ data }) => {
+ dispatch(fetchNotificationPolicySuccess(data));
+ }).catch(err => {
+ dispatch(fetchNotificationPolicyFail(err));
+ });
+};
+
+export const fetchNotificationRequests = () => (dispatch, getState) => {
+ const params = {};
+
+ if (getState().getIn(['notificationRequests', 'isLoading'])) {
+ return;
+ }
+
+ if (getState().getIn(['notificationRequests', 'items'])?.size > 0) {
+ params.since_id = getState().getIn(['notificationRequests', 'items', 0, 'id']);
+ }
+
+ dispatch(fetchNotificationRequestsRequest());
+
+ api(getState).get('/api/v1/notifications/requests', { params }).then(response => {
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data.map(x => x.account)));
+ dispatch(fetchNotificationRequestsSuccess(response.data, next ? next.uri : null));
+ }).catch(err => {
+ dispatch(fetchNotificationRequestsFail(err));
+ });
+};
+
+export const fetchNotificationRequestsRequest = () => ({
+ type: NOTIFICATION_REQUESTS_FETCH_REQUEST,
+});
+
+export const fetchNotificationRequestsSuccess = (requests, next) => ({
+ type: NOTIFICATION_REQUESTS_FETCH_SUCCESS,
+ requests,
+ next,
+});
+
+export const fetchNotificationRequestsFail = error => ({
+ type: NOTIFICATION_REQUESTS_FETCH_FAIL,
+ error,
+});
+
+export const expandNotificationRequests = () => (dispatch, getState) => {
+ const url = getState().getIn(['notificationRequests', 'next']);
+
+ if (!url || getState().getIn(['notificationRequests', 'isLoading'])) {
+ return;
+ }
+
+ dispatch(expandNotificationRequestsRequest());
+
+ api(getState).get(url).then(response => {
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data.map(x => x.account)));
+ dispatch(expandNotificationRequestsSuccess(response.data, next?.uri));
+ }).catch(err => {
+ dispatch(expandNotificationRequestsFail(err));
+ });
+};
+
+export const expandNotificationRequestsRequest = () => ({
+ type: NOTIFICATION_REQUESTS_EXPAND_REQUEST,
+});
+
+export const expandNotificationRequestsSuccess = (requests, next) => ({
+ type: NOTIFICATION_REQUESTS_EXPAND_SUCCESS,
+ requests,
+ next,
+});
+
+export const expandNotificationRequestsFail = error => ({
+ type: NOTIFICATION_REQUESTS_EXPAND_FAIL,
+ error,
+});
+
+export const fetchNotificationRequest = id => (dispatch, getState) => {
+ const current = getState().getIn(['notificationRequests', 'current']);
+
+ if (current.getIn(['item', 'id']) === id || current.get('isLoading')) {
+ return;
+ }
+
+ dispatch(fetchNotificationRequestRequest(id));
+
+ api(getState).get(`/api/v1/notifications/requests/${id}`).then(({ data }) => {
+ dispatch(fetchNotificationRequestSuccess(data));
+ }).catch(err => {
+ dispatch(fetchNotificationRequestFail(id, err));
+ });
+};
+
+export const fetchNotificationRequestRequest = id => ({
+ type: NOTIFICATION_REQUEST_FETCH_REQUEST,
+ id,
+});
+
+export const fetchNotificationRequestSuccess = request => ({
+ type: NOTIFICATION_REQUEST_FETCH_SUCCESS,
+ request,
+});
+
+export const fetchNotificationRequestFail = (id, error) => ({
+ type: NOTIFICATION_REQUEST_FETCH_FAIL,
+ id,
+ error,
+});
+
+export const acceptNotificationRequest = id => (dispatch, getState) => {
+ dispatch(acceptNotificationRequestRequest(id));
+
+ api(getState).post(`/api/v1/notifications/requests/${id}/accept`).then(() => {
+ dispatch(acceptNotificationRequestSuccess(id));
+ }).catch(err => {
+ dispatch(acceptNotificationRequestFail(id, err));
+ });
+};
+
+export const acceptNotificationRequestRequest = id => ({
+ type: NOTIFICATION_REQUEST_ACCEPT_REQUEST,
+ id,
+});
+
+export const acceptNotificationRequestSuccess = id => ({
+ type: NOTIFICATION_REQUEST_ACCEPT_SUCCESS,
+ id,
+});
+
+export const acceptNotificationRequestFail = (id, error) => ({
+ type: NOTIFICATION_REQUEST_ACCEPT_FAIL,
+ id,
+ error,
+});
+
+export const dismissNotificationRequest = id => (dispatch, getState) => {
+ dispatch(dismissNotificationRequestRequest(id));
+
+ api(getState).post(`/api/v1/notifications/requests/${id}/dismiss`).then(() =>{
+ dispatch(dismissNotificationRequestSuccess(id));
+ }).catch(err => {
+ dispatch(dismissNotificationRequestFail(id, err));
+ });
+};
+
+export const dismissNotificationRequestRequest = id => ({
+ type: NOTIFICATION_REQUEST_DISMISS_REQUEST,
+ id,
+});
+
+export const dismissNotificationRequestSuccess = id => ({
+ type: NOTIFICATION_REQUEST_DISMISS_SUCCESS,
+ id,
+});
+
+export const dismissNotificationRequestFail = (id, error) => ({
+ type: NOTIFICATION_REQUEST_DISMISS_FAIL,
+ id,
+ error,
+});
+
+export const fetchNotificationsForRequest = accountId => (dispatch, getState) => {
+ const current = getState().getIn(['notificationRequests', 'current']);
+ const params = { account_id: accountId };
+
+ if (current.getIn(['item', 'account']) === accountId) {
+ if (current.getIn(['notifications', 'isLoading'])) {
+ return;
+ }
+
+ if (current.getIn(['notifications', 'items'])?.size > 0) {
+ params.since_id = current.getIn(['notifications', 'items', 0, 'id']);
+ }
+ }
+
+ dispatch(fetchNotificationsForRequestRequest());
+
+ api(getState).get('/api/v1/notifications', { params }).then(response => {
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data.map(item => item.account)));
+ dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
+ dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
+
+ dispatch(fetchNotificationsForRequestSuccess(response.data, next?.uri));
+ }).catch(err => {
+ dispatch(fetchNotificationsForRequestFail(err));
+ });
+};
+
+export const fetchNotificationsForRequestRequest = () => ({
+ type: NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST,
+});
+
+export const fetchNotificationsForRequestSuccess = (notifications, next) => ({
+ type: NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS,
+ notifications,
+ next,
+});
+
+export const fetchNotificationsForRequestFail = (error) => ({
+ type: NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL,
+ error,
+});
+
+export const expandNotificationsForRequest = () => (dispatch, getState) => {
+ const url = getState().getIn(['notificationRequests', 'current', 'notifications', 'next']);
+
+ if (!url || getState().getIn(['notificationRequests', 'current', 'notifications', 'isLoading'])) {
+ return;
+ }
+
+ dispatch(expandNotificationsForRequestRequest());
+
+ api(getState).get(url).then(response => {
+ const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data.map(item => item.account)));
+ dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
+ dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
+
+ dispatch(expandNotificationsForRequestSuccess(response.data, next?.uri));
+ }).catch(err => {
+ dispatch(expandNotificationsForRequestFail(err));
+ });
+};
+
+export const expandNotificationsForRequestRequest = () => ({
+ type: NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST,
+});
+
+export const expandNotificationsForRequestSuccess = (notifications, next) => ({
+ type: NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS,
+ notifications,
+ next,
+});
+
+export const expandNotificationsForRequestFail = (error) => ({
+ type: NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL,
+ error,
+});
diff --git a/app/javascript/flavours/glitch/actions/search.js b/app/javascript/flavours/glitch/actions/search.js
index 7e54740d52..44344e2fb5 100644
--- a/app/javascript/flavours/glitch/actions/search.js
+++ b/app/javascript/flavours/glitch/actions/search.js
@@ -143,11 +143,14 @@ export const showSearch = () => ({
type: SEARCH_SHOW,
});
-export const openURL = routerHistory => (dispatch, getState) => {
- const value = getState().getIn(['search', 'value']);
+export const openURL = (value, history, onFailure) => (dispatch, getState) => {
const signedIn = !!getState().getIn(['meta', 'me']);
if (!signedIn) {
+ if (onFailure) {
+ onFailure();
+ }
+
return;
}
@@ -156,15 +159,21 @@ export const openURL = routerHistory => (dispatch, getState) => {
api(getState).get('/api/v2/search', { params: { q: value, resolve: true } }).then(response => {
if (response.data.accounts?.length > 0) {
dispatch(importFetchedAccounts(response.data.accounts));
- routerHistory.push(`/@${response.data.accounts[0].acct}`);
+ history.push(`/@${response.data.accounts[0].acct}`);
} else if (response.data.statuses?.length > 0) {
dispatch(importFetchedStatuses(response.data.statuses));
- routerHistory.push(`/@${response.data.statuses[0].account.acct}/${response.data.statuses[0].id}`);
+ history.push(`/@${response.data.statuses[0].account.acct}/${response.data.statuses[0].id}`);
+ } else if (onFailure) {
+ onFailure();
}
dispatch(fetchSearchSuccess(response.data, value));
}).catch(err => {
dispatch(fetchSearchFail(err));
+
+ if (onFailure) {
+ onFailure();
+ }
});
};
diff --git a/app/javascript/flavours/glitch/actions/statuses.js b/app/javascript/flavours/glitch/actions/statuses.js
index 5bdd31c343..332057ee67 100644
--- a/app/javascript/flavours/glitch/actions/statuses.js
+++ b/app/javascript/flavours/glitch/actions/statuses.js
@@ -1,7 +1,7 @@
import api from '../api';
import { ensureComposeIsVisible, setComposeToStatus } from './compose';
-import { importFetchedStatus, importFetchedStatuses } from './importer';
+import { importFetchedStatus, importFetchedStatuses, importFetchedAccount } from './importer';
import { deleteFromTimelines } from './timelines';
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
@@ -138,10 +138,10 @@ export function deleteStatus(id, routerHistory, withRedraft = false) {
api(getState).delete(`/api/v1/statuses/${id}`).then(response => {
dispatch(deleteStatusSuccess(id));
dispatch(deleteFromTimelines(id));
+ dispatch(importFetchedAccount(response.data.account));
if (withRedraft) {
dispatch(redraft(status, response.data.text, response.data.content_type));
-
ensureComposeIsVisible(getState, routerHistory);
}
}).catch(error => {
diff --git a/app/javascript/flavours/glitch/actions/suggestions.js b/app/javascript/flavours/glitch/actions/suggestions.js
index 870a311024..8eafe38b21 100644
--- a/app/javascript/flavours/glitch/actions/suggestions.js
+++ b/app/javascript/flavours/glitch/actions/suggestions.js
@@ -54,12 +54,5 @@ export const dismissSuggestion = accountId => (dispatch, getState) => {
id: accountId,
});
- api(getState).delete(`/api/v1/suggestions/${accountId}`).then(() => {
- dispatch(fetchSuggestionsRequest());
-
- api(getState).get('/api/v2/suggestions').then(response => {
- dispatch(importFetchedAccounts(response.data.map(x => x.account)));
- dispatch(fetchSuggestionsSuccess(response.data));
- }).catch(error => dispatch(fetchSuggestionsFail(error)));
- }).catch(() => {});
+ api(getState).delete(`/api/v1/suggestions/${accountId}`).catch(() => {});
};
diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js
index fa69bca985..980b4af66d 100644
--- a/app/javascript/flavours/glitch/actions/timelines.js
+++ b/app/javascript/flavours/glitch/actions/timelines.js
@@ -22,6 +22,10 @@ export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL';
+export const TIMELINE_INSERT = 'TIMELINE_INSERT';
+
+export const TIMELINE_SUGGESTIONS = 'inline-follow-suggestions';
+export const TIMELINE_GAP = null;
export const loadPending = timeline => ({
type: TIMELINE_LOAD_PENDING,
@@ -123,9 +127,19 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
api(getState).get(path, { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+
dispatch(importFetchedStatuses(response.data));
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore, isLoadingRecent && preferPendingItems));
+ if (timelineId === 'home' && !isLoadingMore && !isLoadingRecent) {
+ const now = new Date();
+ const fittingIndex = response.data.findIndex(status => now - (new Date(status.created_at)) > 4 * 3600 * 1000);
+
+ if (fittingIndex !== -1) {
+ dispatch(insertIntoTimeline(timelineId, TIMELINE_SUGGESTIONS, Math.max(1, fittingIndex)));
+ }
+ }
+
if (timelineId === 'home') {
dispatch(submitMarkers());
}
@@ -233,3 +247,10 @@ export const markAsPartial = timeline => ({
type: TIMELINE_MARK_AS_PARTIAL,
timeline,
});
+
+export const insertIntoTimeline = (timeline, key, index) => ({
+ type: TIMELINE_INSERT,
+ timeline,
+ index,
+ key,
+});
diff --git a/app/javascript/flavours/glitch/api_types/accounts.ts b/app/javascript/flavours/glitch/api_types/accounts.ts
index 3347a970fb..5bf3e64288 100644
--- a/app/javascript/flavours/glitch/api_types/accounts.ts
+++ b/app/javascript/flavours/glitch/api_types/accounts.ts
@@ -43,4 +43,5 @@ export interface ApiAccountJSON {
suspended?: boolean;
limited?: boolean;
memorial?: boolean;
+ hide_collections: boolean;
}
diff --git a/app/javascript/flavours/glitch/components/account.jsx b/app/javascript/flavours/glitch/components/account.jsx
index 266a3ca995..7e5209653e 100644
--- a/app/javascript/flavours/glitch/components/account.jsx
+++ b/app/javascript/flavours/glitch/components/account.jsx
@@ -37,10 +37,10 @@ class Account extends ImmutablePureComponent {
static propTypes = {
size: PropTypes.number,
account: ImmutablePropTypes.record,
- onFollow: PropTypes.func.isRequired,
- onBlock: PropTypes.func.isRequired,
- onMute: PropTypes.func.isRequired,
- onMuteNotifications: PropTypes.func.isRequired,
+ onFollow: PropTypes.func,
+ onBlock: PropTypes.func,
+ onMute: PropTypes.func,
+ onMuteNotifications: PropTypes.func,
intl: PropTypes.object.isRequired,
hidden: PropTypes.bool,
minimal: PropTypes.bool,
@@ -147,7 +147,7 @@ class Account extends ImmutablePureComponent {