mirror of
https://github.com/mastodon/mastodon.git
synced 2024-08-20 21:08:15 -07:00
Merge branch 'main' into media-display-options
This commit is contained in:
commit
1b1687967a
1591 changed files with 42594 additions and 19289 deletions
|
@ -1,7 +1,9 @@
|
|||
[production]
|
||||
defaults
|
||||
not IE 11
|
||||
> 0.2%
|
||||
ios >= 15.6
|
||||
not dead
|
||||
not OperaMini all
|
||||
|
||||
[development]
|
||||
supports es6-module
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
ignore:
|
||||
# devise-two-factor advisory about brute-forcing TOTP
|
||||
# We have rate-limits on authentication endpoints in place (including second
|
||||
# factor verification) since Mastodon v3.2.0
|
||||
- CVE-2024-0227
|
|
@ -1,20 +1,15 @@
|
|||
# For details, see https://github.com/devcontainers/images/tree/main/src/ruby
|
||||
FROM mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye
|
||||
FROM mcr.microsoft.com/devcontainers/ruby:1-3.3-bookworm
|
||||
|
||||
# Install Rails
|
||||
# RUN gem install rails webdrivers
|
||||
# Install node version from .nvmrc
|
||||
WORKDIR /app
|
||||
COPY .nvmrc .
|
||||
RUN /bin/bash --login -i -c "nvm install"
|
||||
|
||||
ARG NODE_VERSION="20"
|
||||
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"
|
||||
# Install additional OS packages
|
||||
RUN apt-get update && \
|
||||
export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libpam-dev
|
||||
|
||||
# [Optional] Uncomment this line to install additional gems.
|
||||
RUN gem install foreman
|
||||
|
||||
# [Optional] Uncomment this line to install global node packages.
|
||||
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && corepack enable" 2>&1
|
||||
|
||||
COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
||||
# Move welcome message to where VS Code expects it
|
||||
COPY .devcontainer/welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"name": "Mastodon on GitHub Codespaces",
|
||||
"dockerComposeFile": "../docker-compose.yml",
|
||||
"dockerComposeFile": "../compose.yaml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/sshd:1": {},
|
||||
"ghcr.io/devcontainers/features/sshd:1": {}
|
||||
},
|
||||
|
||||
"runServices": ["app", "db", "redis"],
|
||||
|
@ -15,16 +15,18 @@
|
|||
"portsAttributes": {
|
||||
"3000": {
|
||||
"label": "web",
|
||||
"onAutoForward": "notify",
|
||||
"onAutoForward": "notify"
|
||||
},
|
||||
"4000": {
|
||||
"label": "stream",
|
||||
"onAutoForward": "silent",
|
||||
},
|
||||
"onAutoForward": "silent"
|
||||
}
|
||||
},
|
||||
|
||||
"remoteUser": "root",
|
||||
|
||||
"otherPortsAttributes": {
|
||||
"onAutoForward": "silent",
|
||||
"onAutoForward": "silent"
|
||||
},
|
||||
|
||||
"remoteEnv": {
|
||||
|
@ -33,17 +35,17 @@
|
|||
"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}",
|
||||
"postCreateCommand": ".devcontainer/post-create.sh",
|
||||
"postCreateCommand": "bin/setup",
|
||||
"waitFor": "postCreateCommand",
|
||||
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"],
|
||||
},
|
||||
},
|
||||
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
version: '3'
|
||||
|
||||
services:
|
||||
app:
|
||||
working_dir: /workspaces/mastodon/
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
context: ..
|
||||
dockerfile: .devcontainer/Dockerfile
|
||||
volumes:
|
||||
- ../..:/workspaces:cached
|
||||
- ..:/workspaces/mastodon:cached
|
||||
environment:
|
||||
RAILS_ENV: development
|
||||
NODE_ENV: development
|
||||
|
@ -70,7 +69,7 @@ services:
|
|||
hard: -1
|
||||
|
||||
libretranslate:
|
||||
image: libretranslate/libretranslate:v1.5.4
|
||||
image: libretranslate/libretranslate:v1.5.7
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- lt-data:/home/libretranslate/.local
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"name": "Mastodon on local machine",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"dockerComposeFile": "compose.yaml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/sshd:1": {},
|
||||
"ghcr.io/devcontainers/features/sshd:1": {}
|
||||
},
|
||||
|
||||
"forwardPorts": [3000, 4000],
|
||||
|
@ -14,27 +14,29 @@
|
|||
"3000": {
|
||||
"label": "web",
|
||||
"onAutoForward": "notify",
|
||||
"requireLocalPort": true,
|
||||
"requireLocalPort": true
|
||||
},
|
||||
"4000": {
|
||||
"label": "stream",
|
||||
"onAutoForward": "silent",
|
||||
"requireLocalPort": true,
|
||||
},
|
||||
"requireLocalPort": true
|
||||
}
|
||||
},
|
||||
|
||||
"remoteUser": "root",
|
||||
|
||||
"otherPortsAttributes": {
|
||||
"onAutoForward": "silent",
|
||||
"onAutoForward": "silent"
|
||||
},
|
||||
|
||||
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
|
||||
"postCreateCommand": ".devcontainer/post-create.sh",
|
||||
"postCreateCommand": "bin/setup",
|
||||
"waitFor": "postCreateCommand",
|
||||
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"settings": {},
|
||||
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"],
|
||||
},
|
||||
},
|
||||
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e # Fail the whole script on first error
|
||||
|
||||
# Fetch Ruby gem dependencies
|
||||
bundle config path 'vendor/bundle'
|
||||
bundle config with 'development test'
|
||||
bundle install
|
||||
|
||||
# Make Gemfile.lock pristine again
|
||||
git checkout -- Gemfile.lock
|
||||
|
||||
# Fetch Javascript dependencies
|
||||
corepack prepare
|
||||
yarn install --immutable
|
||||
|
||||
# [re]create, migrate, and seed the test database
|
||||
RAILS_ENV=test ./bin/rails db:setup
|
||||
|
||||
# [re]create, migrate, and seed the development database
|
||||
RAILS_ENV=development ./bin/rails db:setup
|
||||
|
||||
# Precompile assets for development
|
||||
RAILS_ENV=development ./bin/rails assets:precompile
|
||||
|
||||
# Precompile assets for test
|
||||
RAILS_ENV=test ./bin/rails assets:precompile
|
|
@ -1,8 +1,7 @@
|
|||
👋 Welcome to "Mastodon" in GitHub Codespaces!
|
||||
👋 Welcome to your Mastodon Dev Container!
|
||||
|
||||
🛠️ Your environment is fully setup with all the required software.
|
||||
🛠️ Your environment is fully setup with all the required software.
|
||||
|
||||
🔍 To explore VS Code to its fullest, search using the Command Palette (Cmd/Ctrl + Shift + P or F1).
|
||||
|
||||
📝 Edit away, run your app as usual, and we'll automatically make it available for you to access.
|
||||
💥 Run `bin/dev` to start the application processes.
|
||||
|
||||
🥼 Run `RAILS_ENV=test bin/rails assets:precompile && RAILS_ENV=test bin/rspec` to run the test suite.
|
||||
|
|
4
.env.development
Normal file
4
.env.development
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Required by ActiveRecord encryption feature
|
||||
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR
|
||||
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E
|
||||
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr
|
|
@ -3,3 +3,9 @@ NODE_ENV=production
|
|||
# Federation
|
||||
LOCAL_DOMAIN=cb6e6126.ngrok.io
|
||||
LOCAL_HTTPS=true
|
||||
|
||||
# Secret values required by ActiveRecord encryption feature
|
||||
# Use `bin/rails db:encryption:init` to generate fresh secrets
|
||||
ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=test_determinist_key_DO_NOT_USE_IN_PRODUCTION
|
||||
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=test_salt_DO_NOT_USE_IN_PRODUCTION
|
||||
ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=test_primary_key_DO_NOT_USE_IN_PRODUCTION
|
||||
|
|
39
.eslintrc.js
39
.eslintrc.js
|
@ -20,10 +20,6 @@ module.exports = defineConfig({
|
|||
es6: true,
|
||||
},
|
||||
|
||||
globals: {
|
||||
ATTACHMENT_HOST: false,
|
||||
},
|
||||
|
||||
parser: '@typescript-eslint/parser',
|
||||
|
||||
plugins: [
|
||||
|
@ -79,7 +75,7 @@ module.exports = defineConfig({
|
|||
],
|
||||
},
|
||||
],
|
||||
'no-empty': 'off',
|
||||
'no-empty': ['error', { "allowEmptyCatch": true }],
|
||||
'no-restricted-properties': [
|
||||
'error',
|
||||
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
||||
|
@ -94,7 +90,6 @@ module.exports = defineConfig({
|
|||
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
||||
},
|
||||
],
|
||||
'no-self-assign': 'off',
|
||||
'no-unused-expressions': 'error',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
|
@ -119,12 +114,10 @@ module.exports = defineConfig({
|
|||
'react/jsx-tag-spacing': 'error',
|
||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
||||
'react/jsx-wrap-multilines': 'error',
|
||||
'react/no-deprecated': 'off',
|
||||
'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
|
||||
'jsx-a11y/accessible-emoji': 'warn',
|
||||
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
|
||||
'jsx-a11y/click-events-have-key-events': 'off',
|
||||
'jsx-a11y/label-has-associated-control': 'off',
|
||||
'jsx-a11y/media-has-caption': 'off',
|
||||
|
@ -139,23 +132,6 @@ module.exports = defineConfig({
|
|||
// ],
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
||||
// recommended rule is:
|
||||
// 'jsx-a11y/no-noninteractive-element-interactions': [
|
||||
// 'error',
|
||||
// {
|
||||
// body: ['onError', 'onLoad'],
|
||||
// iframe: ['onError', 'onLoad'],
|
||||
// img: ['onError', 'onLoad'],
|
||||
// },
|
||||
// ],
|
||||
'jsx-a11y/no-noninteractive-element-interactions': [
|
||||
'warn',
|
||||
{
|
||||
handlers: [
|
||||
'onClick',
|
||||
],
|
||||
},
|
||||
],
|
||||
// recommended rule is:
|
||||
// 'jsx-a11y/no-noninteractive-tabindex': [
|
||||
// 'error',
|
||||
// {
|
||||
|
@ -165,7 +141,6 @@ module.exports = defineConfig({
|
|||
// },
|
||||
// ],
|
||||
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
||||
'jsx-a11y/no-onchange': 'off',
|
||||
// recommended is full 'error'
|
||||
'jsx-a11y/no-static-element-interactions': [
|
||||
'warn',
|
||||
|
@ -176,7 +151,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',
|
||||
|
@ -338,7 +313,6 @@ module.exports = defineConfig({
|
|||
'plugin:import/typescript',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:jsdoc/recommended-typescript',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
|
@ -347,6 +321,12 @@ module.exports = defineConfig({
|
|||
},
|
||||
|
||||
rules: {
|
||||
// Disable formatting rules that have been enabled in the base config
|
||||
'indent': 'off',
|
||||
|
||||
// This is not needed as we use noImplicitReturns, which handles this in addition to understanding types
|
||||
'consistent-return': 'off',
|
||||
|
||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
||||
|
||||
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
|
||||
|
@ -361,6 +341,7 @@ module.exports = defineConfig({
|
|||
"message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead."
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/restrict-template-expressions": ['warn', { allowNumber: true }],
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
|
||||
// Those rules set stricter rules for TS files
|
||||
|
|
2
.github/actions/setup-ruby/action.yml
vendored
2
.github/actions/setup-ruby/action.yml
vendored
|
@ -14,7 +14,7 @@ runs:
|
|||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libicu-dev libidn11-dev ${{ inputs.additional-system-dependencies }}
|
||||
sudo apt-get install -y libicu-dev libidn11-dev libvips42 ${{ inputs.additional-system-dependencies }}
|
||||
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
|
|
8
.github/codecov.yml
vendored
8
.github/codecov.yml
vendored
|
@ -1,13 +1,11 @@
|
|||
comment: false # Do not leave PR comments
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
# Github status check is not blocking
|
||||
# GitHub status check is not blocking
|
||||
informational: true
|
||||
patch:
|
||||
default:
|
||||
# Github status check is not blocking
|
||||
# GitHub status check is not blocking
|
||||
informational: true
|
||||
comment:
|
||||
# Only write a comment in PR if there are changes
|
||||
require_changes: true
|
||||
|
|
29
.github/renovate.json5
vendored
29
.github/renovate.json5
vendored
|
@ -2,6 +2,7 @@
|
|||
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
|
||||
extends: [
|
||||
'config:recommended',
|
||||
'customManagers:dockerfileVersions',
|
||||
':labels(dependencies)',
|
||||
':prConcurrentLimitNone', // Remove limit for open PRs at any time.
|
||||
':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour.
|
||||
|
@ -13,6 +14,9 @@
|
|||
// to `null` after any other rule set it to something.
|
||||
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
|
||||
postUpdateOptions: ['yarnDedupeHighest'],
|
||||
lockFileMaintenance: {
|
||||
enabled: true,
|
||||
},
|
||||
packageRules: [
|
||||
{
|
||||
// Require Dependency Dashboard Approval for major version bumps of these node packages
|
||||
|
@ -59,7 +63,7 @@
|
|||
dependencyDashboardApproval: true,
|
||||
},
|
||||
{
|
||||
// Update Github Actions and Docker images weekly
|
||||
// Update GitHub Actions and Docker images weekly
|
||||
matchManagers: ['github-actions', 'dockerfile', 'docker-compose'],
|
||||
extends: ['schedule:weekly'],
|
||||
},
|
||||
|
@ -125,6 +129,29 @@
|
|||
],
|
||||
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)',
|
||||
},
|
||||
{
|
||||
// Group all opentelemetry-ruby packages in the same PR
|
||||
matchManagers: ['bundler'],
|
||||
matchPackagePrefixes: ['opentelemetry-'],
|
||||
matchUpdateTypes: ['patch', 'minor'],
|
||||
groupName: 'opentelemetry-ruby (non-major)',
|
||||
},
|
||||
// Add labels depending on package manager
|
||||
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
|
||||
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },
|
||||
|
|
21
.github/stylelint-matcher.json
vendored
21
.github/stylelint-matcher.json
vendored
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "stylelint",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^([^\\s].*)$",
|
||||
"file": 1
|
||||
},
|
||||
{
|
||||
"regexp": "^\\s+((\\d+):(\\d+))?\\s+(✖|×)\\s+(.*)\\s{2,}(.*)$",
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 5,
|
||||
"code": 6,
|
||||
"loop": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
2
.github/workflows/build-container-image.yml
vendored
2
.github/workflows/build-container-image.yml
vendored
|
@ -68,7 +68,7 @@ jobs:
|
|||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Log in to the Github Container registry
|
||||
- name: Log in to the GitHub Container registry
|
||||
if: contains(inputs.push_to_images, 'ghcr.io')
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
|
|
4
.github/workflows/build-security.yml
vendored
4
.github/workflows/build-security.yml
vendored
|
@ -38,7 +38,7 @@ jobs:
|
|||
tags: |
|
||||
type=raw,value=edge
|
||||
type=raw,value=nightly
|
||||
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
|
||||
type=raw,value=${{ needs.compute-suffix.outputs.prerelease }}
|
||||
secrets: inherit
|
||||
|
||||
build-image-streaming:
|
||||
|
@ -60,5 +60,5 @@ jobs:
|
|||
tags: |
|
||||
type=raw,value=edge
|
||||
type=raw,value=nightly
|
||||
type=schedule,pattern=${{ needs.compute-suffix.outputs.prerelease }}
|
||||
type=raw,value=${{ needs.compute-suffix.outputs.prerelease }}
|
||||
secrets: inherit
|
||||
|
|
13
.github/workflows/bundler-audit.yml
vendored
13
.github/workflows/bundler-audit.yml
vendored
|
@ -6,14 +6,12 @@ on:
|
|||
paths:
|
||||
- 'Gemfile*'
|
||||
- '.ruby-version'
|
||||
- '.bundler-audit.yml'
|
||||
- '.github/workflows/bundler-audit.yml'
|
||||
|
||||
pull_request:
|
||||
paths:
|
||||
- 'Gemfile*'
|
||||
- '.ruby-version'
|
||||
- '.bundler-audit.yml'
|
||||
- '.github/workflows/bundler-audit.yml'
|
||||
|
||||
schedule:
|
||||
|
@ -23,12 +21,17 @@ jobs:
|
|||
security:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
BUNDLE_ONLY: development
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
|
||||
- name: Run bundler-audit
|
||||
run: bundle exec bundler-audit
|
||||
run: bundle exec bundler-audit check --update
|
||||
|
|
6
.github/workflows/crowdin-download.yml
vendored
6
.github/workflows/crowdin-download.yml
vendored
|
@ -52,19 +52,19 @@ 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.5
|
||||
with:
|
||||
commit-message: 'New Crowdin translations'
|
||||
title: 'New Crowdin Translations (automated)'
|
||||
author: 'GitHub Actions <noreply@github.com>'
|
||||
body: |
|
||||
New Crowdin translations, automated with Github Actions
|
||||
New Crowdin translations, automated with GitHub Actions
|
||||
|
||||
See `.github/workflows/crowdin-download.yml`
|
||||
|
||||
This PR will be updated every day with new translations.
|
||||
|
||||
Due to a limitation in Github Actions, checks are not running on this PR without manual action.
|
||||
Due to a limitation in GitHub Actions, checks are not running on this PR without manual action.
|
||||
If you want to run the checks, then close and re-open it.
|
||||
branch: i18n/crowdin/translations
|
||||
base: main
|
||||
|
|
18
.github/workflows/format-check.yml
vendored
Normal file
18
.github/workflows/format-check.yml
vendored
Normal file
|
@ -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
|
6
.github/workflows/lint-css.yml
vendored
6
.github/workflows/lint-css.yml
vendored
|
@ -38,9 +38,5 @@ jobs:
|
|||
- name: Set up Javascript environment
|
||||
uses: ./.github/actions/setup-javascript
|
||||
|
||||
- uses: xt0rted/stylelint-problem-matcher@v1
|
||||
|
||||
- run: echo "::add-matcher::.github/stylelint-matcher.json"
|
||||
|
||||
- name: Stylelint
|
||||
run: yarn lint:sass
|
||||
run: yarn lint:css -f github
|
||||
|
|
12
.github/workflows/lint-haml.yml
vendored
12
.github/workflows/lint-haml.yml
vendored
|
@ -26,14 +26,20 @@ on:
|
|||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
BUNDLE_ONLY: development
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
|
||||
- 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
|
||||
|
|
38
.github/workflows/lint-json.yml
vendored
38
.github/workflows/lint-json.yml
vendored
|
@ -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
|
38
.github/workflows/lint-md.yml
vendored
38
.github/workflows/lint-md.yml
vendored
|
@ -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
|
13
.github/workflows/lint-ruby.yml
vendored
13
.github/workflows/lint-ruby.yml
vendored
|
@ -27,19 +27,24 @@ jobs:
|
|||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
BUNDLE_ONLY: development
|
||||
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
|
||||
- name: Set-up RuboCop Problem Matcher
|
||||
uses: r7kamura/rubocop-problem-matchers-action@v1
|
||||
|
||||
- name: Run rubocop
|
||||
run: bundle exec rubocop
|
||||
run: bin/rubocop
|
||||
|
||||
- name: Run brakeman
|
||||
if: always() # Run both checks, even if the first failed
|
||||
run: bundle exec brakeman
|
||||
run: bin/brakeman
|
||||
|
|
40
.github/workflows/lint-yml.yml
vendored
40
.github/workflows/lint-yml.yml
vendored
|
@ -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
|
2
.github/workflows/rebase-needed.yml
vendored
2
.github/workflows/rebase-needed.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Check for merge conflicts
|
||||
uses: eps1lon/actions-label-merge-conflict@releases/2.x
|
||||
uses: eps1lon/actions-label-merge-conflict@v3
|
||||
with:
|
||||
dirtyLabel: 'rebase needed :construction:'
|
||||
repoToken: '${{ secrets.GITHUB_TOKEN }}'
|
||||
|
|
2
.github/workflows/test-js.yml
vendored
2
.github/workflows/test-js.yml
vendored
|
@ -38,5 +38,5 @@ jobs:
|
|||
- name: Set up Javascript environment
|
||||
uses: ./.github/actions/setup-javascript
|
||||
|
||||
- name: Jest testing
|
||||
- name: JavaScript testing
|
||||
run: yarn jest --reporters github-actions summary
|
||||
|
|
95
.github/workflows/test-migrations-two-step.yml
vendored
95
.github/workflows/test-migrations-two-step.yml
vendored
|
@ -1,95 +0,0 @@
|
|||
name: Test two step migrations
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**'
|
||||
- 'renovate/**'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pre_job:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
should_skip: ${{ steps.skip_check.outputs.should_skip }}
|
||||
|
||||
steps:
|
||||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml", "lib/tasks/tests.rake"]'
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
needs: pre_job
|
||||
if: needs.pre_job.outputs.should_skip != 'true'
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
matrix:
|
||||
postgres:
|
||||
- 14-alpine
|
||||
- 15-alpine
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:${{ matrix.postgres}}
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
env:
|
||||
CONTINUOUS_INTEGRATION: true
|
||||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
DISABLE_SIMPLECOV: true
|
||||
RAILS_ENV: test
|
||||
BUNDLE_CLEAN: true
|
||||
BUNDLE_FROZEN: true
|
||||
BUNDLE_WITHOUT: 'development production'
|
||||
BUNDLE_JOBS: 3
|
||||
BUNDLE_RETRY: 3
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
|
||||
- name: Create database
|
||||
run: './bin/rails db:create'
|
||||
|
||||
- name: Run historical migrations with data population
|
||||
run: './bin/rails tests:migrations:prepare_database'
|
||||
env:
|
||||
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
|
||||
|
||||
- name: Run all remaining pre-deployment migrations
|
||||
run: './bin/rails db:migrate'
|
||||
env:
|
||||
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
|
||||
|
||||
- name: Run all post-deployment migrations
|
||||
run: './bin/rails db:migrate'
|
||||
|
||||
- name: Check migration result
|
||||
run: './bin/rails tests:migrations:check_database'
|
|
@ -1,4 +1,5 @@
|
|||
name: Test one step migrations
|
||||
name: Historical data migration test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
|
@ -17,7 +18,7 @@ jobs:
|
|||
- id: skip_check
|
||||
uses: fkirc/skip-duplicate-actions@v5
|
||||
with:
|
||||
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml", "lib/tasks/tests.rake"]'
|
||||
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations.yml", "lib/tasks/tests.rake"]'
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -40,9 +41,9 @@ jobs:
|
|||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
|
@ -50,14 +51,13 @@ jobs:
|
|||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
env:
|
||||
CONTINUOUS_INTEGRATION: true
|
||||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
|
@ -65,7 +65,7 @@ jobs:
|
|||
RAILS_ENV: test
|
||||
BUNDLE_CLEAN: true
|
||||
BUNDLE_FROZEN: true
|
||||
BUNDLE_WITHOUT: 'development production'
|
||||
BUNDLE_WITHOUT: 'development:production'
|
||||
BUNDLE_JOBS: 3
|
||||
BUNDLE_RETRY: 3
|
||||
|
||||
|
@ -75,14 +75,19 @@ jobs:
|
|||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
|
||||
- name: Create database
|
||||
run: './bin/rails db:create'
|
||||
- name: Test "one step migration" flow
|
||||
run: |
|
||||
bin/rails db:drop
|
||||
bin/rails db:create
|
||||
bin/rails tests:migrations:prepare_database
|
||||
bin/rails db:migrate
|
||||
bin/rails tests:migrations:check_database
|
||||
|
||||
- name: Run historical migrations with data population
|
||||
run: './bin/rails tests:migrations:prepare_database'
|
||||
|
||||
- name: Run all remaining migrations
|
||||
run: './bin/rails db:migrate'
|
||||
|
||||
- name: Check migration result
|
||||
run: './bin/rails tests:migrations:check_database'
|
||||
- name: Test "two step migration" flow
|
||||
run: |
|
||||
bin/rails db:drop
|
||||
bin/rails db:create
|
||||
SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails tests:migrations:prepare_database
|
||||
SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails db:migrate
|
||||
bin/rails db:migrate
|
||||
bin/rails tests:migrations:check_database
|
184
.github/workflows/test-ruby.yml
vendored
184
.github/workflows/test-ruby.yml
vendored
|
@ -28,8 +28,7 @@ jobs:
|
|||
env:
|
||||
RAILS_ENV: ${{ matrix.mode }}
|
||||
BUNDLE_WITH: ${{ matrix.mode }}
|
||||
OTP_SECRET: precompile_placeholder
|
||||
SECRET_KEY_BASE: precompile_placeholder
|
||||
SECRET_KEY_BASE_DUMMY: 1
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
@ -74,9 +73,9 @@ jobs:
|
|||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
|
@ -84,9 +83,9 @@ jobs:
|
|||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
|
@ -111,8 +110,8 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
ruby-version:
|
||||
- '3.0'
|
||||
- '3.1'
|
||||
- '3.2'
|
||||
- '.ruby-version'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
@ -130,7 +129,7 @@ jobs:
|
|||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg imagemagick libpam-dev
|
||||
additional-system-dependencies: ffmpeg libpam-dev
|
||||
|
||||
- name: Load database schema
|
||||
run: './bin/rails db:create db:schema:load db:seed'
|
||||
|
@ -139,9 +138,98 @@ 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
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
test-libvips:
|
||||
name: Libvips tests
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
needs:
|
||||
- build
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14-alpine
|
||||
env:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
env:
|
||||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
DISABLE_SIMPLECOV: ${{ matrix.ruby-version != '.ruby-version' }}
|
||||
RAILS_ENV: test
|
||||
ALLOW_NOPAM: true
|
||||
PAM_ENABLED: true
|
||||
PAM_DEFAULT_SERVICE: pam_test
|
||||
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
||||
OIDC_ENABLED: true
|
||||
OIDC_SCOPE: read
|
||||
SAML_ENABLED: true
|
||||
CAS_ENABLED: true
|
||||
BUNDLE_WITH: 'pam_authentication test'
|
||||
GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' && github.event.pull_request && 'true' }}
|
||||
MASTODON_USE_LIBVIPS: true
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ruby-version:
|
||||
- '3.1'
|
||||
- '3.2'
|
||||
- '.ruby-version'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: './'
|
||||
name: ${{ github.sha }}
|
||||
|
||||
- name: Expand archived asset artifacts
|
||||
run: |
|
||||
tar xvzf artifacts.tar.gz
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg libpam-dev libyaml-dev
|
||||
|
||||
- name: Load database schema
|
||||
run: './bin/rails db:create db:schema:load db:seed'
|
||||
|
||||
- run: bin/rspec --tag paperclip_processing
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: matrix.ruby-version == '.ruby-version'
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: coverage/lcov/mastodon.lcov
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
test-e2e:
|
||||
name: End to End testing
|
||||
|
@ -158,9 +246,9 @@ jobs:
|
|||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
|
@ -168,9 +256,9 @@ jobs:
|
|||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
|
@ -181,13 +269,15 @@ jobs:
|
|||
DISABLE_SIMPLECOV: true
|
||||
RAILS_ENV: test
|
||||
BUNDLE_WITH: test
|
||||
LOCAL_DOMAIN: localhost:3000
|
||||
LOCAL_HTTPS: false
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ruby-version:
|
||||
- '3.0'
|
||||
- '3.1'
|
||||
- '3.2'
|
||||
- '.ruby-version'
|
||||
|
||||
steps:
|
||||
|
@ -195,14 +285,18 @@ jobs:
|
|||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: './public'
|
||||
path: './'
|
||||
name: ${{ github.sha }}
|
||||
|
||||
- name: Expand archived asset artifacts
|
||||
run: |
|
||||
tar xvzf artifacts.tar.gz
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg imagemagick
|
||||
additional-system-dependencies: ffmpeg
|
||||
|
||||
- name: Set up Javascript environment
|
||||
uses: ./.github/actions/setup-javascript
|
||||
|
@ -210,7 +304,7 @@ jobs:
|
|||
- name: Load database schema
|
||||
run: './bin/rails db:create db:schema:load db:seed'
|
||||
|
||||
- run: bundle exec rake spec:system
|
||||
- run: bin/rspec spec/system --tag streaming --tag js
|
||||
|
||||
- name: Archive logs
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -224,7 +318,7 @@ jobs:
|
|||
if: failure()
|
||||
with:
|
||||
name: e2e-screenshots
|
||||
path: tmp/screenshots/
|
||||
path: tmp/capybara/
|
||||
|
||||
test-search:
|
||||
name: Elastic Search integration testing
|
||||
|
@ -241,9 +335,9 @@ jobs:
|
|||
POSTGRES_USER: postgres
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 5432:5432
|
||||
|
||||
|
@ -251,22 +345,36 @@ jobs:
|
|||
image: redis:7-alpine
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
--health-interval 10ms
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
search:
|
||||
image: ${{ matrix.search-image }}
|
||||
elasticsearch:
|
||||
image: ${{ contains(matrix.search-image, 'elasticsearch') && matrix.search-image || '' }}
|
||||
env:
|
||||
discovery.type: single-node
|
||||
xpack.security.enabled: false
|
||||
options: >-
|
||||
--health-cmd "curl http://localhost:9200/_cluster/health"
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
--health-interval 2s
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 9200:9200
|
||||
|
||||
opensearch:
|
||||
image: ${{ contains(matrix.search-image, 'opensearch') && matrix.search-image || '' }}
|
||||
env:
|
||||
discovery.type: single-node
|
||||
DISABLE_INSTALL_DEMO_CONFIG: true
|
||||
DISABLE_SECURITY_PLUGIN: true
|
||||
options: >-
|
||||
--health-cmd "curl http://localhost:9200/_cluster/health"
|
||||
--health-interval 2s
|
||||
--health-timeout 3s
|
||||
--health-retries 50
|
||||
ports:
|
||||
- 9200:9200
|
||||
|
||||
|
@ -285,28 +393,30 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
ruby-version:
|
||||
- '3.0'
|
||||
- '3.1'
|
||||
- '3.2'
|
||||
- '.ruby-version'
|
||||
search-image:
|
||||
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
|
||||
include:
|
||||
- ruby-version: '.ruby-version'
|
||||
search-image: docker.elastic.co/elasticsearch/elasticsearch:8.10.2
|
||||
- ruby-version: '.ruby-version'
|
||||
search-image: opensearchproject/opensearch:2
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: './public'
|
||||
path: './'
|
||||
name: ${{ github.sha }}
|
||||
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg imagemagick
|
||||
additional-system-dependencies: ffmpeg
|
||||
|
||||
- name: Set up Javascript environment
|
||||
uses: ./.github/actions/setup-javascript
|
||||
|
@ -328,4 +438,4 @@ jobs:
|
|||
if: failure()
|
||||
with:
|
||||
name: test-search-screenshots
|
||||
path: tmp/screenshots/
|
||||
path: tmp/capybara/
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -24,7 +24,6 @@
|
|||
/public/packs-test
|
||||
.env
|
||||
.env.production
|
||||
.env.development
|
||||
/node_modules/
|
||||
/build/
|
||||
|
||||
|
@ -69,3 +68,6 @@ yarn-debug.log
|
|||
|
||||
# Ignore Docker option files
|
||||
docker-compose.override.yml
|
||||
|
||||
# Ignore dotenv .local files
|
||||
.env*.local
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
inherits_from: .haml-lint_todo.yml
|
||||
|
||||
exclude:
|
||||
- 'vendor/**/*'
|
||||
- lib/templates/haml/scaffold/_form.html.haml
|
||||
|
||||
require:
|
||||
- ./lib/linter/haml_middle_dot.rb
|
||||
|
@ -13,4 +10,6 @@ linters:
|
|||
MiddleDot:
|
||||
enabled: true
|
||||
LineLength:
|
||||
max: 320
|
||||
max: 300
|
||||
ViewLength:
|
||||
max: 200 # Override default value of 100 inherited from rubocop
|
||||
|
|
|
@ -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'
|
|
@ -1,4 +1 @@
|
|||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn lint-staged
|
||||
|
|
19
.nanoignore
19
.nanoignore
|
@ -1,19 +0,0 @@
|
|||
.DS_Store
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
.bundle/
|
||||
.cache/
|
||||
config/deploy/*
|
||||
coverage
|
||||
docs/
|
||||
.env
|
||||
log/*.log
|
||||
neo4j/
|
||||
node_modules/
|
||||
public/assets/
|
||||
public/system/
|
||||
spec/
|
||||
tmp/
|
||||
.vagrant/
|
||||
vendor/bundle/
|
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
|||
20.11
|
||||
20.15
|
||||
|
|
|
@ -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,4 +81,5 @@ app/javascript/styles/mastodon/reset.scss
|
|||
# Ignore the generated AUTHORS.md
|
||||
AUTHORS.md
|
||||
|
||||
# Process a few selected JS files
|
||||
!lint-staged.config.js
|
||||
|
|
249
.rubocop.yml
249
.rubocop.yml
|
@ -1,7 +1,27 @@
|
|||
# Can be removed once all rules are addressed or moved to this file as documented overrides
|
||||
inherit_from: .rubocop_todo.yml
|
||||
---
|
||||
AllCops:
|
||||
CacheRootDirectory: tmp
|
||||
DisplayStyleGuide: true
|
||||
Exclude:
|
||||
- Vagrantfile
|
||||
- config/initializers/json_ld*
|
||||
- lib/mastodon/migration_helpers.rb
|
||||
ExtraDetails: true
|
||||
NewCops: enable
|
||||
TargetRubyVersion: 3.1 # Oldest supported ruby version
|
||||
|
||||
inherit_from:
|
||||
- .rubocop/layout.yml
|
||||
- .rubocop/metrics.yml
|
||||
- .rubocop/naming.yml
|
||||
- .rubocop/rails.yml
|
||||
- .rubocop/rspec_rails.yml
|
||||
- .rubocop/rspec.yml
|
||||
- .rubocop/style.yml
|
||||
- .rubocop/custom.yml
|
||||
- .rubocop_todo.yml
|
||||
- .rubocop/strict.yml
|
||||
|
||||
# Used for merging with exclude lists with .rubocop_todo.yml
|
||||
inherit_mode:
|
||||
merge:
|
||||
- Exclude
|
||||
|
@ -9,227 +29,6 @@ inherit_mode:
|
|||
require:
|
||||
- rubocop-rails
|
||||
- rubocop-rspec
|
||||
- rubocop-rspec_rails
|
||||
- rubocop-performance
|
||||
- rubocop-capybara
|
||||
- ./lib/linter/rubocop_middle_dot
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 3.0 # Set to minimum supported version of CI
|
||||
DisplayCopNames: true
|
||||
DisplayStyleGuide: true
|
||||
ExtraDetails: true
|
||||
UseCache: true
|
||||
CacheRootDirectory: tmp
|
||||
NewCops: enable # Opt-in to newly added rules
|
||||
Exclude:
|
||||
- db/schema.rb
|
||||
- 'bin/*'
|
||||
- 'node_modules/**/*'
|
||||
- 'Vagrantfile'
|
||||
- 'vendor/**/*'
|
||||
- 'config/initializers/json_ld*' # Generated files
|
||||
- 'lib/mastodon/migration_helpers.rb' # Vendored from GitLab
|
||||
- 'lib/templates/**/*'
|
||||
|
||||
# Reason: Prefer Hashes without extreme indentation
|
||||
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation
|
||||
Layout/FirstHashElementIndentation:
|
||||
EnforcedStyle: consistent
|
||||
|
||||
# Reason: Currently disabled in .rubocop_todo.yml
|
||||
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength
|
||||
Layout/LineLength:
|
||||
Max: 320 # Default of 120 causes a duplicate entry in generated todo file
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier
|
||||
Lint/UselessAccessModifier:
|
||||
ContextCreatingMethods:
|
||||
- class_methods
|
||||
|
||||
## Disable most Metrics/*Length cops
|
||||
# Reason: those are often triggered and force significant refactors when this happend
|
||||
# but the team feel they are not really improving the code quality.
|
||||
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength
|
||||
Metrics/BlockLength:
|
||||
Enabled: false
|
||||
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength
|
||||
Metrics/ModuleLength:
|
||||
Enabled: false
|
||||
|
||||
## End Disable Metrics/*Length cops
|
||||
|
||||
# Reason: Currently disabled in .rubocop_todo.yml
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize
|
||||
Metrics/AbcSize:
|
||||
Exclude:
|
||||
- 'lib/mastodon/cli/*.rb'
|
||||
|
||||
# Reason: Currently disabled in .rubocop_todo.yml
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity
|
||||
Metrics/CyclomaticComplexity:
|
||||
Exclude:
|
||||
- lib/mastodon/cli/*.rb
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists
|
||||
Metrics/ParameterLists:
|
||||
CountKeywordArgs: false
|
||||
|
||||
# Reason: Prevailing style is argument file paths
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath
|
||||
Rails/FilePath:
|
||||
EnforcedStyle: arguments
|
||||
|
||||
# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
|
||||
Rails/HttpStatus:
|
||||
EnforcedStyle: numeric
|
||||
|
||||
# Reason: Allowed in boot ENV checker
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
|
||||
Rails/Exit:
|
||||
Exclude:
|
||||
- 'config/boot.rb'
|
||||
|
||||
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
|
||||
Rails/LexicallyScopedActionFilter:
|
||||
Exclude:
|
||||
- 'app/controllers/auth/*'
|
||||
|
||||
# Reason: These tasks are doing local work which do not need full env loaded
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsrakeenvironment
|
||||
Rails/RakeEnvironment:
|
||||
Exclude:
|
||||
- 'lib/tasks/auto_annotate_models.rake'
|
||||
- 'lib/tasks/emojis.rake'
|
||||
- 'lib/tasks/mastodon.rake'
|
||||
- 'lib/tasks/repo.rake'
|
||||
- 'lib/tasks/statistics.rake'
|
||||
|
||||
# Reason: There are appropriate times to use these features
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsskipsmodelvalidations
|
||||
Rails/SkipsModelValidations:
|
||||
Enabled: false
|
||||
|
||||
# Reason: We want to preserve the ability to migrate from arbitrary old versions,
|
||||
# and cannot guarantee that every installation has run every migration as they upgrade.
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns
|
||||
Rails/UnusedIgnoredColumns:
|
||||
Enabled: false
|
||||
|
||||
# Reason: Prevailing style choice
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude
|
||||
Rails/NegateInclude:
|
||||
Enabled: false
|
||||
|
||||
# Reason: Deprecated cop, will be removed in 3.0, replaced by SpecFilePathFormat
|
||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
|
||||
RSpec/FilePath:
|
||||
Enabled: false
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject
|
||||
RSpec/NamedSubject:
|
||||
EnforcedStyle: named_only
|
||||
|
||||
# Reason: Prevailing style choice
|
||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot
|
||||
RSpec/NotToNot:
|
||||
EnforcedStyle: to_not
|
||||
|
||||
# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus
|
||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
|
||||
RSpec/Rails/HttpStatus:
|
||||
EnforcedStyle: numeric
|
||||
|
||||
# Reason: Match overrides from Rspec/FilePath rule above
|
||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecspecfilepathformat
|
||||
RSpec/SpecFilePathFormat:
|
||||
CustomTransform:
|
||||
ActivityPub: activitypub
|
||||
DeepL: deepl
|
||||
FetchOEmbedService: fetch_oembed_service
|
||||
OEmbedController: oembed_controller
|
||||
OStatus: ostatus
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren
|
||||
Style/ClassAndModuleChildren:
|
||||
Enabled: false
|
||||
|
||||
# Reason: Classes mostly self-document with their names
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation
|
||||
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:
|
||||
EnforcedStyle: ruby19_no_mixed_keys
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals
|
||||
Style/NumericLiterals:
|
||||
AllowedPatterns:
|
||||
- \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters
|
||||
Style/PercentLiteralDelimiters:
|
||||
PreferredDelimiters:
|
||||
'%i': '()'
|
||||
'%w': '()'
|
||||
|
||||
# Reason: Prefer less indentation in conditional assignments
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin
|
||||
Style/RedundantBegin:
|
||||
Enabled: false
|
||||
|
||||
# Reason: Overridden to reduce implicit StandardError rescues
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror
|
||||
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:
|
||||
Enabled: false
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
EnforcedStyleForMultiline: 'comma'
|
||||
|
||||
# Reason:
|
||||
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: 'comma'
|
||||
|
||||
Style/MiddleDot:
|
||||
Enabled: true
|
||||
|
|
6
.rubocop/custom.yml
Normal file
6
.rubocop/custom.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
require:
|
||||
- ../lib/linter/rubocop_middle_dot
|
||||
|
||||
Style/MiddleDot:
|
||||
Enabled: true
|
6
.rubocop/layout.yml
Normal file
6
.rubocop/layout.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
Layout/FirstHashElementIndentation:
|
||||
EnforcedStyle: consistent
|
||||
|
||||
Layout/LineLength:
|
||||
Max: 300 # Default of 120 causes a duplicate entry in generated todo file
|
23
.rubocop/metrics.yml
Normal file
23
.rubocop/metrics.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
Metrics/AbcSize:
|
||||
Exclude:
|
||||
- lib/mastodon/cli/*.rb
|
||||
|
||||
Metrics/BlockLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ClassLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/CyclomaticComplexity:
|
||||
Exclude:
|
||||
- lib/mastodon/cli/*.rb
|
||||
|
||||
Metrics/MethodLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ModuleLength:
|
||||
Enabled: false
|
||||
|
||||
Metrics/ParameterLists:
|
||||
CountKeywordArgs: false
|
3
.rubocop/naming.yml
Normal file
3
.rubocop/naming.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
Naming/BlockForwarding:
|
||||
EnforcedStyle: explicit
|
23
.rubocop/rails.yml
Normal file
23
.rubocop/rails.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
Rails/FilePath:
|
||||
EnforcedStyle: arguments
|
||||
|
||||
Rails/HttpStatus:
|
||||
EnforcedStyle: numeric
|
||||
|
||||
Rails/NegateInclude:
|
||||
Enabled: false
|
||||
|
||||
Rails/RakeEnvironment:
|
||||
Exclude: # Tasks are doing local work which do not need full env loaded
|
||||
- lib/tasks/auto_annotate_models.rake
|
||||
- lib/tasks/emojis.rake
|
||||
- lib/tasks/mastodon.rake
|
||||
- lib/tasks/repo.rake
|
||||
- lib/tasks/statistics.rake
|
||||
|
||||
Rails/SkipsModelValidations:
|
||||
Enabled: false
|
||||
|
||||
Rails/UnusedIgnoredColumns:
|
||||
Enabled: false # Preserve ability to migrate from arbitrary old versions
|
27
.rubocop/rspec.yml
Normal file
27
.rubocop/rspec.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
RSpec/ExampleLength:
|
||||
CountAsOne: ['array', 'heredoc', 'method_call']
|
||||
Max: 20 # Override default of 5
|
||||
|
||||
RSpec/MultipleExpectations:
|
||||
Max: 10 # Overrides default of 1
|
||||
|
||||
RSpec/MultipleMemoizedHelpers:
|
||||
Max: 20 # Overrides default of 5
|
||||
|
||||
RSpec/NamedSubject:
|
||||
EnforcedStyle: named_only
|
||||
|
||||
RSpec/NestedGroups:
|
||||
Max: 10 # Overrides default of 3
|
||||
|
||||
RSpec/NotToNot:
|
||||
EnforcedStyle: to_not
|
||||
|
||||
RSpec/SpecFilePathFormat:
|
||||
CustomTransform:
|
||||
ActivityPub: activitypub
|
||||
DeepL: deepl
|
||||
FetchOEmbedService: fetch_oembed_service
|
||||
OEmbedController: oembed_controller
|
||||
OStatus: ostatus
|
3
.rubocop/rspec_rails.yml
Normal file
3
.rubocop/rspec_rails.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
RSpecRails/HttpStatus:
|
||||
EnforcedStyle: numeric
|
19
.rubocop/strict.yml
Normal file
19
.rubocop/strict.yml
Normal file
|
@ -0,0 +1,19 @@
|
|||
Lint/Debugger: # Remove any `binding.pry`
|
||||
Enabled: true
|
||||
Exclude: []
|
||||
|
||||
RSpec/Focus: # Require full spec run on CI
|
||||
Enabled: true
|
||||
Exclude: []
|
||||
|
||||
Rails/Output: # Remove any `puts` debugging
|
||||
Enabled: true
|
||||
Exclude: []
|
||||
|
||||
Rails/FindEach: # Using `each` could impact performance, use `find_each`
|
||||
Enabled: true
|
||||
Exclude: []
|
||||
|
||||
Rails/UniqBeforePluck: # Require `uniq.pluck` and not `pluck.uniq`
|
||||
Enabled: true
|
||||
Exclude: []
|
47
.rubocop/style.yml
Normal file
47
.rubocop/style.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
Style/ClassAndModuleChildren:
|
||||
Enabled: false
|
||||
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
||||
Style/FormatStringToken:
|
||||
AllowedMethods:
|
||||
- redirect_with_vary # Route redirects are not token-formatted
|
||||
inherit_mode:
|
||||
merge:
|
||||
- AllowedMethods
|
||||
|
||||
Style/HashAsLastArrayItem:
|
||||
Enabled: false
|
||||
|
||||
Style/HashSyntax:
|
||||
EnforcedShorthandSyntax: either
|
||||
EnforcedStyle: ruby19_no_mixed_keys
|
||||
|
||||
Style/NumericLiterals:
|
||||
AllowedPatterns:
|
||||
- \d{4}_\d{2}_\d{2}_\d{6}
|
||||
|
||||
Style/PercentLiteralDelimiters:
|
||||
PreferredDelimiters:
|
||||
'%i': ()
|
||||
'%w': ()
|
||||
|
||||
Style/RedundantBegin:
|
||||
Enabled: false
|
||||
|
||||
Style/RedundantFetchBlock:
|
||||
Enabled: false
|
||||
|
||||
Style/RescueStandardError:
|
||||
EnforcedStyle: implicit
|
||||
|
||||
Style/SymbolArray:
|
||||
Enabled: false
|
||||
|
||||
Style/TrailingCommaInArrayLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
|
@ -1,18 +1,11 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.60.2.
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.64.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
# versions of RuboCop, may require this file to be generated again.
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
|
||||
# Include: **/*.gemfile, **/Gemfile, **/gems.rb
|
||||
Bundler/OrderedGems:
|
||||
Exclude:
|
||||
- 'Gemfile'
|
||||
|
||||
Lint/NonLocalExitFromIterator:
|
||||
Exclude:
|
||||
- 'app/helpers/jsonld_helper.rb'
|
||||
|
@ -34,61 +27,16 @@ Metrics/CyclomaticComplexity:
|
|||
Metrics/PerceivedComplexity:
|
||||
Max: 27
|
||||
|
||||
# Configuration parameters: CountAsOne.
|
||||
RSpec/ExampleLength:
|
||||
Max: 22
|
||||
|
||||
RSpec/MultipleExpectations:
|
||||
Max: 8
|
||||
|
||||
# Configuration parameters: AllowSubject.
|
||||
RSpec/MultipleMemoizedHelpers:
|
||||
Max: 17
|
||||
|
||||
# Configuration parameters: AllowedGroups.
|
||||
RSpec/NestedGroups:
|
||||
Max: 6
|
||||
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/HasAndBelongsToMany:
|
||||
Exclude:
|
||||
- 'app/models/concerns/account/associations.rb'
|
||||
- 'app/models/status.rb'
|
||||
- 'app/models/tag.rb'
|
||||
|
||||
Rails/OutputSafety:
|
||||
Exclude:
|
||||
- 'config/initializers/simple_form.rb'
|
||||
|
||||
# Configuration parameters: Include.
|
||||
# Include: app/models/**/*.rb
|
||||
Rails/UniqueValidationWithoutIndex:
|
||||
Exclude:
|
||||
- 'app/models/account_alias.rb'
|
||||
- 'app/models/custom_filter_status.rb'
|
||||
- 'app/models/identity.rb'
|
||||
- 'app/models/webauthn_credential.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
||||
# AllowedMethods: ==, equal?, eql?
|
||||
Style/ClassEqualityComparison:
|
||||
Exclude:
|
||||
- 'app/helpers/jsonld_helper.rb'
|
||||
- 'app/serializers/activitypub/outbox_serializer.rb'
|
||||
|
||||
Style/ClassVars:
|
||||
Exclude:
|
||||
- 'config/initializers/devise.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: AllowedVars.
|
||||
Style/FetchEnvVar:
|
||||
Exclude:
|
||||
- 'app/lib/redis_configuration.rb'
|
||||
- 'app/lib/translation_service.rb'
|
||||
- 'config/environments/development.rb'
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/initializers/2_limited_federation_mode.rb'
|
||||
- 'config/initializers/3_omniauth.rb'
|
||||
|
@ -98,9 +46,7 @@ Style/FetchEnvVar:
|
|||
- 'config/initializers/paperclip.rb'
|
||||
- 'config/initializers/vapid.rb'
|
||||
- 'lib/mastodon/redis_config.rb'
|
||||
- 'lib/premailer_webpack_strategy.rb'
|
||||
- 'lib/tasks/repo.rake'
|
||||
- 'spec/features/profile_spec.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
||||
|
@ -111,54 +57,10 @@ Style/FormatStringToken:
|
|||
- 'config/initializers/devise.rb'
|
||||
- 'lib/paperclip/color_extractor.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/GlobalStdStream:
|
||||
Exclude:
|
||||
- 'config/environments/development.rb'
|
||||
- 'config/environments/production.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
||||
Style/GuardClause:
|
||||
Exclude:
|
||||
- 'app/lib/activitypub/activity/block.rb'
|
||||
- 'app/lib/request.rb'
|
||||
- 'app/lib/request_pool.rb'
|
||||
- 'app/lib/webfinger.rb'
|
||||
- 'app/lib/webfinger_resource.rb'
|
||||
- 'app/models/concerns/account/counters.rb'
|
||||
- 'app/models/concerns/user/ldap_authenticable.rb'
|
||||
- 'app/models/tag.rb'
|
||||
- 'app/models/user.rb'
|
||||
- 'app/services/fan_out_on_write_service.rb'
|
||||
- 'app/services/post_status_service.rb'
|
||||
- 'app/services/process_hashtags_service.rb'
|
||||
- 'app/workers/move_worker.rb'
|
||||
- 'app/workers/redownload_avatar_worker.rb'
|
||||
- 'app/workers/redownload_header_worker.rb'
|
||||
- 'app/workers/redownload_media_worker.rb'
|
||||
- 'app/workers/remote_account_refresh_worker.rb'
|
||||
- 'config/initializers/devise.rb'
|
||||
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
||||
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
||||
- 'lib/mastodon/cli/accounts.rb'
|
||||
- 'lib/mastodon/cli/maintenance.rb'
|
||||
- 'lib/mastodon/cli/media.rb'
|
||||
- 'lib/paperclip/attachment_extensions.rb'
|
||||
- 'lib/tasks/repo.rake'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: braces, no_braces
|
||||
Style/HashAsLastArrayItem:
|
||||
Exclude:
|
||||
- 'app/controllers/admin/statuses_controller.rb'
|
||||
- 'app/controllers/api/v1/statuses_controller.rb'
|
||||
- 'app/models/concerns/account/counters.rb'
|
||||
- 'app/models/concerns/status/threading_concern.rb'
|
||||
- 'app/models/status.rb'
|
||||
- 'app/services/batched_remove_status_service.rb'
|
||||
- 'app/services/notify_service.rb'
|
||||
Enabled: false
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/HashTransformValues:
|
||||
|
@ -166,13 +68,6 @@ Style/HashTransformValues:
|
|||
- 'app/serializers/rest/web_push_subscription_serializer.rb'
|
||||
- 'app/services/import_service.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
Style/IfUnlessModifier:
|
||||
Exclude:
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/initializers/devise.rb'
|
||||
- 'config/initializers/ffmpeg.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/MapToHash:
|
||||
Exclude:
|
||||
|
@ -187,16 +82,10 @@ Style/MutableConstant:
|
|||
- 'app/services/delete_account_service.rb'
|
||||
- 'lib/mastodon/migration_warning.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
Style/NilLambda:
|
||||
Exclude:
|
||||
- 'config/initializers/paperclip.rb'
|
||||
|
||||
# Configuration parameters: AllowedMethods.
|
||||
# AllowedMethods: respond_to_missing?
|
||||
Style/OptionalBooleanParameter:
|
||||
Exclude:
|
||||
- 'app/helpers/admin/account_moderation_notes_helper.rb'
|
||||
- 'app/helpers/jsonld_helper.rb'
|
||||
- 'app/lib/admin/system_check/message.rb'
|
||||
- 'app/lib/request.rb'
|
||||
|
@ -207,13 +96,6 @@ Style/OptionalBooleanParameter:
|
|||
- 'app/workers/unfollow_follow_worker.rb'
|
||||
- 'lib/mastodon/redis_config.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: PreferredDelimiters.
|
||||
Style/PercentLiteralDelimiters:
|
||||
Exclude:
|
||||
- 'config/deploy.rb'
|
||||
- 'config/initializers/doorkeeper.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: short, verbose
|
||||
|
@ -227,69 +109,6 @@ Style/RedundantConstantBase:
|
|||
- 'config/environments/production.rb'
|
||||
- 'config/initializers/sidekiq.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: SafeForConstants.
|
||||
Style/RedundantFetchBlock:
|
||||
Exclude:
|
||||
- 'config/initializers/1_hosts.rb'
|
||||
- 'config/initializers/chewy.rb'
|
||||
- 'config/initializers/devise.rb'
|
||||
- 'config/initializers/paperclip.rb'
|
||||
- 'config/puma.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
||||
# AllowedMethods: present?, blank?, presence, try, try!
|
||||
Style/SafeNavigation:
|
||||
Exclude:
|
||||
- 'app/models/concerns/account/finder_concern.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: only_raise, only_fail, semantic
|
||||
Style/SignalException:
|
||||
Exclude:
|
||||
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
||||
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/SingleArgumentDig:
|
||||
Exclude:
|
||||
- 'lib/webpacker/manifest_extensions.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: Mode.
|
||||
Style/StringConcatenation:
|
||||
Exclude:
|
||||
- 'config/initializers/paperclip.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
||||
# SupportedStyles: single_quotes, double_quotes
|
||||
Style/StringLiterals:
|
||||
Exclude:
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/initializers/backtrace_silencers.rb'
|
||||
- 'config/initializers/http_client_proxy.rb'
|
||||
- 'config/initializers/rack_attack.rb'
|
||||
- 'config/initializers/webauthn.rb'
|
||||
- 'config/routes.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyleForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInArguments:
|
||||
Exclude:
|
||||
- 'config/initializers/paperclip.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyleForMultiline.
|
||||
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
Exclude:
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/environments/test.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: WordRegex.
|
||||
# SupportedStyles: percent, brackets
|
||||
|
|
|
@ -1 +1 @@
|
|||
3.2.3
|
||||
3.3.3
|
||||
|
|
22
.simplecov
22
.simplecov
|
@ -1,22 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if ENV['CI']
|
||||
require 'simplecov-lcov'
|
||||
SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
|
||||
SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
|
||||
else
|
||||
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
||||
end
|
||||
|
||||
SimpleCov.start 'rails' do
|
||||
enable_coverage :branch
|
||||
|
||||
add_filter 'lib/linter'
|
||||
|
||||
add_group 'Libraries', 'lib'
|
||||
add_group 'Policies', 'app/policies'
|
||||
add_group 'Presenters', 'app/presenters'
|
||||
add_group 'Serializers', 'app/serializers'
|
||||
add_group 'Services', 'app/services'
|
||||
add_group 'Validators', 'app/validators'
|
||||
end
|
150
CHANGELOG.md
150
CHANGELOG.md
|
@ -2,6 +2,156 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.2.9] - 2024-05-30
|
||||
|
||||
### Security
|
||||
|
||||
- Update dependencies
|
||||
- Fix private mention filtering ([GHSA-5fq7-3p3j-9vrf](https://github.com/mastodon/mastodon/security/advisories/GHSA-5fq7-3p3j-9vrf))
|
||||
- Fix password change endpoint not being rate-limited ([GHSA-q3rg-xx5v-4mxh](https://github.com/mastodon/mastodon/security/advisories/GHSA-q3rg-xx5v-4mxh))
|
||||
- Add hardening around rate-limit bypass ([GHSA-c2r5-cfqr-c553](https://github.com/mastodon/mastodon/security/advisories/GHSA-c2r5-cfqr-c553))
|
||||
|
||||
### Added
|
||||
|
||||
- Add rate-limit on OAuth application registration ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30316))
|
||||
- Add fallback redirection when getting a webfinger query `WEB_DOMAIN@WEB_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28592))
|
||||
- Add `digest` attribute to `Admin::DomainBlock` entity in REST API ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/29092))
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove superfluous application-level caching in some controllers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29862))
|
||||
- Remove aggressive OAuth application vacuuming ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30316))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix leaking Elasticsearch connections in Sidekiq processes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30450))
|
||||
- Fix language of remote posts not being recognized when using unusual casing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30403))
|
||||
- Fix off-by-one in `tootctl media` commands ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30306))
|
||||
- Fix removal of allowed domains (in `LIMITED_FEDERATION_MODE`) not being recorded in the audit log ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30125))
|
||||
- Fix not being able to block a subdomain of an already-blocked domain through the API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30119))
|
||||
- Fix `Idempotency-Key` being ignored when scheduling a post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30084))
|
||||
- Fix crash when supplying the `FFMPEG_BINARY` environment variable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30022))
|
||||
- Fix improper email address validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29838))
|
||||
- Fix results/query in `api/v1/featured_tags/suggestions` ([mjankowski](https://github.com/mastodon/mastodon/pull/29597))
|
||||
- Fix unblocking internationalized domain names under certain conditions ([tribela](https://github.com/mastodon/mastodon/pull/29530))
|
||||
- Fix admin account created by `mastodon:setup` not being auto-approved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29379))
|
||||
- Fix reference to non-existent var in CLI maintenance command ([mjankowski](https://github.com/mastodon/mastodon/pull/28363))
|
||||
|
||||
## [4.2.8] - 2024-02-23
|
||||
|
||||
### Added
|
||||
|
||||
- Add hourly task to automatically require approval for new registrations in the absence of moderators ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29318), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/29355))
|
||||
In order to prevent future abandoned Mastodon servers from being used for spam, harassment and other malicious activity, Mastodon will now automatically switch new user registrations to require moderator approval whenever they are left open and no activity (including non-moderation actions from apps) from any logged-in user with permission to access moderation reports has been detected in a full week.
|
||||
When this happens, users with the permission to change server settings will receive an email notification.
|
||||
This feature is disabled when `EMAIL_DOMAIN_ALLOWLIST` is used, and can also be disabled with `DISABLE_AUTOMATIC_SWITCHING_TO_APPROVED_REGISTRATIONS=true`.
|
||||
|
||||
### Changed
|
||||
|
||||
- Change registrations to be closed by default on new installations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29280))
|
||||
If you are running a server and never changed your registrations mode from the default, updating will automatically close your registrations.
|
||||
Simply re-enable them through the administration interface or using `tootctl settings registrations open` if you want to enable them again.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix processing of remote ActivityPub actors making use of `Link` objects as `Image` `url` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29335))
|
||||
- Fix link verifications when page size exceeds 1MB ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29358))
|
||||
|
||||
## [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
|
||||
|
|
184
Dockerfile
184
Dockerfile
|
@ -1,4 +1,7 @@
|
|||
# syntax=docker/dockerfile:1.4
|
||||
# syntax=docker/dockerfile:1.8
|
||||
|
||||
# This file is designed for production server deployment, not local development work
|
||||
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
|
||||
|
||||
# Please see https://docs.docker.com/engine/reference/builder for information about
|
||||
# the extended buildx capabilities used in this file.
|
||||
|
@ -7,29 +10,31 @@
|
|||
ARG TARGETPLATFORM=${TARGETPLATFORM}
|
||||
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
||||
|
||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.3"]
|
||||
ARG RUBY_VERSION="3.2.3"
|
||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"]
|
||||
# renovate: datasource=docker depName=docker.io/ruby
|
||||
ARG RUBY_VERSION="3.3.3"
|
||||
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||
# renovate: datasource=node-version depName=node
|
||||
ARG NODE_MAJOR_VERSION="20"
|
||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||
ARG DEBIAN_VERSION="bookworm"
|
||||
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
|
||||
# Ruby image to use for base image based on combined variables (ex: 3.2.3-slim-bookworm)
|
||||
# Ruby image to use for base image based on combined variables (ex: 3.3.x-slim-bookworm)
|
||||
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"]
|
||||
# Example: v4.3.0-nightly.2023.11.09+pr-123456
|
||||
# Overwrite existence of 'alpha.X' 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"]
|
||||
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"]
|
||||
ARG MASTODON_VERSION_METADATA=""
|
||||
|
||||
# Allow Ruby on Rails to serve static files
|
||||
# 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_4/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"
|
||||
|
@ -60,7 +65,9 @@ ENV \
|
|||
DEBIAN_FRONTEND="noninteractive" \
|
||||
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \
|
||||
# Optimize jemalloc 5.x performance
|
||||
MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0"
|
||||
MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0" \
|
||||
# Enable libvips, should not be changed
|
||||
MASTODON_USE_LIBVIPS=true
|
||||
|
||||
# Set default shell used for running commands
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-c"]
|
||||
|
@ -93,11 +100,8 @@ RUN \
|
|||
apt-get dist-upgrade -yq; \
|
||||
# Install jemalloc, curl and other necessary components
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
ffmpeg \
|
||||
file \
|
||||
imagemagick \
|
||||
libjemalloc2 \
|
||||
patchelf \
|
||||
procps \
|
||||
|
@ -131,18 +135,47 @@ RUN \
|
|||
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
||||
# Install build tools and bundler dependencies from APT
|
||||
apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
gcc \
|
||||
autoconf \
|
||||
automake \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
libgdbm-dev \
|
||||
libglib2.0-dev \
|
||||
libgmp-dev \
|
||||
libicu-dev \
|
||||
libidn-dev \
|
||||
libpq-dev \
|
||||
libssl-dev \
|
||||
make \
|
||||
libtool \
|
||||
meson \
|
||||
nasm \
|
||||
pkg-config \
|
||||
shared-mime-info \
|
||||
zlib1g-dev \
|
||||
xz-utils \
|
||||
# libvips components
|
||||
libcgif-dev \
|
||||
libexif-dev \
|
||||
libexpat1-dev \
|
||||
libgirepository1.0-dev \
|
||||
libheif-dev \
|
||||
libimagequant-dev \
|
||||
libjpeg62-turbo-dev \
|
||||
liblcms2-dev \
|
||||
liborc-dev \
|
||||
libspng-dev \
|
||||
libtiff-dev \
|
||||
libwebp-dev \
|
||||
# ffmpeg components
|
||||
libdav1d-dev \
|
||||
liblzma-dev \
|
||||
libmp3lame-dev \
|
||||
libopus-dev \
|
||||
libsnappy-dev \
|
||||
libvorbis-dev \
|
||||
libvpx-dev \
|
||||
libx264-dev \
|
||||
libx265-dev \
|
||||
;
|
||||
|
||||
RUN \
|
||||
|
@ -151,6 +184,68 @@ RUN \
|
|||
corepack enable; \
|
||||
corepack prepare --activate;
|
||||
|
||||
# Create temporary libvips specific build layer from build layer
|
||||
FROM build as libvips
|
||||
|
||||
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
|
||||
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
|
||||
ARG VIPS_VERSION=8.15.2
|
||||
# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"]
|
||||
ARG VIPS_URL=https://github.com/libvips/libvips/releases/download
|
||||
|
||||
WORKDIR /usr/local/libvips/src
|
||||
|
||||
RUN \
|
||||
curl -sSL -o vips-${VIPS_VERSION}.tar.xz ${VIPS_URL}/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz; \
|
||||
tar xf vips-${VIPS_VERSION}.tar.xz; \
|
||||
cd vips-${VIPS_VERSION}; \
|
||||
meson setup build --prefix /usr/local/libvips --libdir=lib -Ddeprecated=false -Dintrospection=disabled -Dmodules=disabled -Dexamples=false; \
|
||||
cd build; \
|
||||
ninja; \
|
||||
ninja install;
|
||||
|
||||
# Create temporary ffmpeg specific build layer from build layer
|
||||
FROM build as ffmpeg
|
||||
|
||||
# ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"]
|
||||
# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg
|
||||
ARG FFMPEG_VERSION=7.0.1
|
||||
# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"]
|
||||
ARG FFMPEG_URL=https://ffmpeg.org/releases
|
||||
|
||||
WORKDIR /usr/local/ffmpeg/src
|
||||
|
||||
RUN \
|
||||
curl -sSL -o ffmpeg-${FFMPEG_VERSION}.tar.xz ${FFMPEG_URL}/ffmpeg-${FFMPEG_VERSION}.tar.xz; \
|
||||
tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz; \
|
||||
cd ffmpeg-${FFMPEG_VERSION}; \
|
||||
./configure \
|
||||
--prefix=/usr/local/ffmpeg \
|
||||
--toolchain=hardened \
|
||||
--disable-debug \
|
||||
--disable-devices \
|
||||
--disable-doc \
|
||||
--disable-ffplay \
|
||||
--disable-network \
|
||||
--disable-static \
|
||||
--enable-ffmpeg \
|
||||
--enable-ffprobe \
|
||||
--enable-gpl \
|
||||
--enable-libdav1d \
|
||||
--enable-libmp3lame \
|
||||
--enable-libopus \
|
||||
--enable-libsnappy \
|
||||
--enable-libvorbis \
|
||||
--enable-libvpx \
|
||||
--enable-libwebp \
|
||||
--enable-libx264 \
|
||||
--enable-libx265 \
|
||||
--enable-shared \
|
||||
--enable-version3 \
|
||||
; \
|
||||
make -j$(nproc); \
|
||||
make install;
|
||||
|
||||
# Create temporary bundler specific build layer from build layer
|
||||
FROM build as bundler
|
||||
|
||||
|
@ -200,12 +295,17 @@ COPY . /opt/mastodon/
|
|||
COPY --from=yarn /opt/mastodon /opt/mastodon/
|
||||
COPY --from=bundler /opt/mastodon /opt/mastodon/
|
||||
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
||||
# Copy libvips components to layer for precompiler
|
||||
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
RUN \
|
||||
ldconfig; \
|
||||
# Use Ruby on Rails to create Mastodon assets
|
||||
OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile; \
|
||||
SECRET_KEY_BASE_DUMMY=1 \
|
||||
bundle exec rails assets:precompile; \
|
||||
# Cleanup temporary files
|
||||
rm -fr /opt/mastodon/tmp;
|
||||
|
||||
|
@ -224,12 +324,41 @@ RUN \
|
|||
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||
# Apt update install non-dev versions of necessary components
|
||||
apt-get install -y --no-install-recommends \
|
||||
libssl3 \
|
||||
libpq5 \
|
||||
libexpat1 \
|
||||
libglib2.0-0 \
|
||||
libicu72 \
|
||||
libidn12 \
|
||||
libpq5 \
|
||||
libreadline8 \
|
||||
libssl3 \
|
||||
libyaml-0-2 \
|
||||
# libvips components
|
||||
libcgif0 \
|
||||
libexif12 \
|
||||
libheif1 \
|
||||
libimagequant0 \
|
||||
libjpeg62-turbo \
|
||||
liblcms2-2 \
|
||||
liborc-0.4-0 \
|
||||
libspng0 \
|
||||
libtiff6 \
|
||||
libwebp7 \
|
||||
libwebpdemux2 \
|
||||
libwebpmux3 \
|
||||
# ffmpeg components
|
||||
libdav1d6 \
|
||||
libmp3lame0 \
|
||||
libopencore-amrnb0 \
|
||||
libopencore-amrwb0 \
|
||||
libopus0 \
|
||||
libsnappy1v5 \
|
||||
libtheora0 \
|
||||
libvorbis0a \
|
||||
libvorbisenc2 \
|
||||
libvorbisfile3 \
|
||||
libvpx7 \
|
||||
libx264-164 \
|
||||
libx265-199 \
|
||||
;
|
||||
|
||||
# Copy Mastodon sources into final layer
|
||||
|
@ -240,9 +369,22 @@ COPY --from=precompiler /opt/mastodon/public/packs /opt/mastodon/public/packs
|
|||
COPY --from=precompiler /opt/mastodon/public/assets /opt/mastodon/public/assets
|
||||
# Copy bundler components to layer
|
||||
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
||||
# Copy libvips components to layer
|
||||
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||
# Copy ffpmeg components to layer
|
||||
COPY --from=ffmpeg /usr/local/ffmpeg/bin /usr/local/bin
|
||||
COPY --from=ffmpeg /usr/local/ffmpeg/lib /usr/local/lib
|
||||
|
||||
RUN \
|
||||
# Precompile bootsnap code for faster Rails startup
|
||||
ldconfig; \
|
||||
# Smoketest media processors
|
||||
vips -v; \
|
||||
ffmpeg -version; \
|
||||
ffprobe -version;
|
||||
|
||||
RUN \
|
||||
# Precompile bootsnap code for faster Rails startup
|
||||
bundle exec bootsnap precompile --gemfile app/ lib/;
|
||||
|
||||
RUN \
|
||||
|
@ -257,4 +399,4 @@ USER mastodon
|
|||
# Expose default Puma ports
|
||||
EXPOSE 3000
|
||||
# Set container tini as default entry point
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||
|
|
85
Gemfile
85
Gemfile
|
@ -1,37 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby '>= 3.0.0'
|
||||
ruby '>= 3.1.0'
|
||||
|
||||
gem 'puma', '~> 6.3'
|
||||
gem 'rails', '~> 7.1.1'
|
||||
gem 'propshaft'
|
||||
gem 'thor', '~> 1.2'
|
||||
gem 'puma', '~> 6.3'
|
||||
gem 'rack', '~> 2.2.7'
|
||||
gem 'rails', '~> 7.1.1'
|
||||
gem 'thor', '~> 1.2'
|
||||
|
||||
# For why irb is in the Gemfile, see: https://ruby.social/@st0012/111444685161478182
|
||||
gem 'irb', '~> 1.8'
|
||||
|
||||
gem 'dotenv'
|
||||
gem 'haml-rails', '~>2.0'
|
||||
gem 'pg', '~> 1.5'
|
||||
gem 'pghero'
|
||||
gem 'dotenv-rails', '~> 2.8'
|
||||
|
||||
gem 'aws-sdk-s3', '~> 1.123', require: false
|
||||
gem 'blurhash', '~> 0.1'
|
||||
gem 'fog-core', '<= 2.4.0'
|
||||
gem 'fog-openstack', '~> 1.0', require: false
|
||||
gem 'kt-paperclip', '~> 7.2'
|
||||
gem 'md-paperclip-azure', '~> 2.2', require: false
|
||||
gem 'blurhash', '~> 0.1'
|
||||
gem 'ruby-vips', '~> 2.2', require: false
|
||||
|
||||
gem 'active_model_serializers', '~> 0.10'
|
||||
gem 'addressable', '~> 2.8'
|
||||
gem 'bootsnap', '~> 1.17.0', require: false
|
||||
gem 'bootsnap', '~> 1.18.0', require: false
|
||||
gem 'browser'
|
||||
gem 'charlock_holmes', '~> 0.7.7'
|
||||
gem 'chewy', '~> 7.3'
|
||||
gem 'devise', '~> 4.9'
|
||||
gem 'devise-two-factor', '~> 4.1'
|
||||
gem 'devise-two-factor'
|
||||
|
||||
group :pam_authentication, optional: true do
|
||||
gem 'devise_pam_authenticatable2', '~> 9.2'
|
||||
|
@ -39,11 +37,11 @@ end
|
|||
|
||||
gem 'net-ldap', '~> 0.18'
|
||||
|
||||
gem 'omniauth-cas', '~> 3.0.0.beta.1'
|
||||
gem 'omniauth-saml', '~> 2.0'
|
||||
gem 'omniauth_openid_connect', '~> 0.6.1'
|
||||
gem 'omniauth', '~> 2.0'
|
||||
gem 'omniauth-cas', '~> 3.0.0.beta.1'
|
||||
gem 'omniauth_openid_connect', '~> 0.6.1'
|
||||
gem 'omniauth-rails_csrf_protection', '~> 1.0'
|
||||
gem 'omniauth-saml', '~> 2.0'
|
||||
|
||||
gem 'color_diff', '~> 0.1'
|
||||
gem 'csv', '~> 3.2'
|
||||
|
@ -53,48 +51,50 @@ gem 'ed25519', '~> 1.3'
|
|||
gem 'fast_blank', '~> 1.0'
|
||||
gem 'fastimage'
|
||||
gem 'hiredis', '~> 0.6'
|
||||
gem 'redis-namespace', '~> 1.10'
|
||||
gem 'htmlentities', '~> 4.3'
|
||||
gem 'http', '~> 5.1'
|
||||
gem 'http', '~> 5.2.0'
|
||||
gem 'http_accept_language', '~> 2.1'
|
||||
gem 'httplog', '~> 1.6.2'
|
||||
gem 'httplog', '~> 1.7.0'
|
||||
gem 'i18n'
|
||||
gem 'idn-ruby', require: 'idn'
|
||||
gem 'inline_svg'
|
||||
gem 'irb', '~> 1.8'
|
||||
gem 'kaminari', '~> 1.2'
|
||||
gem 'link_header', '~> 0.0'
|
||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||
gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar'
|
||||
gem 'nokogiri', '~> 1.15'
|
||||
gem 'nsa', github: 'jhawthorn/nsa', ref: 'e020fcc3a54d993ab45b7194d89ab720296c111b'
|
||||
gem 'nsa'
|
||||
gem 'oj', '~> 3.14'
|
||||
gem 'ox', '~> 2.14'
|
||||
gem 'parslet'
|
||||
gem 'posix-spawn'
|
||||
gem 'public_suffix', '~> 5.0'
|
||||
gem 'pundit', '~> 2.3'
|
||||
gem 'premailer-rails'
|
||||
gem 'public_suffix', '~> 6.0'
|
||||
gem 'pundit', '~> 2.3'
|
||||
gem 'rack-attack', '~> 6.6'
|
||||
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
||||
gem 'rails-i18n', '~> 7.0'
|
||||
gem 'redcarpet', '~> 3.6'
|
||||
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||
gem 'redis-namespace', '~> 1.10'
|
||||
gem 'rqrcode', '~> 2.2'
|
||||
gem 'ruby-progressbar', '~> 1.13'
|
||||
gem 'sanitize', '~> 6.0'
|
||||
gem 'scenic', '~> 1.7'
|
||||
gem 'sidekiq', '~> 6.5'
|
||||
gem 'sidekiq-bulk', '~> 0.2.0'
|
||||
gem 'sidekiq-scheduler', '~> 5.0'
|
||||
gem 'sidekiq-unique-jobs', '~> 7.1'
|
||||
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 'simple-navigation', '~> 4.4'
|
||||
gem 'stoplight', '~> 4.1'
|
||||
gem 'strong_migrations', '1.8.0'
|
||||
gem 'tty-prompt', '~> 0.23', require: false
|
||||
gem 'twitter-text', '~> 3.1.0'
|
||||
gem 'tzinfo-data', '~> 1.2023'
|
||||
gem 'webauthn', '~> 3.0'
|
||||
gem 'webpacker', '~> 5.4'
|
||||
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
|
||||
gem 'webauthn', '~> 3.0'
|
||||
|
||||
gem 'json-ld'
|
||||
gem 'json-ld-preloaded', '~> 3.2'
|
||||
|
@ -102,6 +102,26 @@ gem 'rdf-normalize', '~> 0.5'
|
|||
|
||||
gem 'private_address_check', '~> 0.5'
|
||||
|
||||
gem 'opentelemetry-api', '~> 1.2.5'
|
||||
|
||||
group :opentelemetry do
|
||||
gem 'opentelemetry-exporter-otlp', '~> 0.28.0', require: false
|
||||
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
|
||||
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
|
||||
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
|
||||
gem 'opentelemetry-instrumentation-excon', '~> 0.22.0', require: false
|
||||
gem 'opentelemetry-instrumentation-faraday', '~> 0.24.1', require: false
|
||||
gem 'opentelemetry-instrumentation-http', '~> 0.23.2', require: false
|
||||
gem 'opentelemetry-instrumentation-http_client', '~> 0.22.3', require: false
|
||||
gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false
|
||||
gem 'opentelemetry-instrumentation-pg', '~> 0.27.1', require: false
|
||||
gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false
|
||||
gem 'opentelemetry-instrumentation-rails', '~> 0.30.0', require: false
|
||||
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
|
||||
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
|
||||
gem 'opentelemetry-sdk', '~> 1.4', require: false
|
||||
end
|
||||
|
||||
group :test do
|
||||
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
|
||||
gem 'rspec-github', '~> 2.4', require: false
|
||||
|
@ -112,8 +132,8 @@ group :test do
|
|||
# RSpec helpers for email specs
|
||||
gem 'email_spec'
|
||||
|
||||
# Extra RSpec extenion methods and helpers for sidekiq
|
||||
gem 'rspec-sidekiq', '~> 4.0'
|
||||
# Extra RSpec extension methods and helpers for sidekiq
|
||||
gem 'rspec-sidekiq', '~> 5.0'
|
||||
|
||||
# Browser integration testing
|
||||
gem 'capybara', '~> 3.39'
|
||||
|
@ -149,6 +169,7 @@ group :development do
|
|||
gem 'rubocop-performance', require: false
|
||||
gem 'rubocop-rails', require: false
|
||||
gem 'rubocop-rspec', require: false
|
||||
gem 'rubocop-rspec_rails', require: false
|
||||
|
||||
# Annotates modules with schema
|
||||
gem 'annotate', '~> 3.2'
|
||||
|
@ -159,7 +180,7 @@ group :development do
|
|||
|
||||
# Preview mail in the browser
|
||||
gem 'letter_opener', '~> 1.8'
|
||||
gem 'letter_opener_web', '~> 2.0'
|
||||
gem 'letter_opener_web', '~> 3.0'
|
||||
|
||||
# Security analysis CLI tools
|
||||
gem 'brakeman', '~> 6.0', require: false
|
||||
|
@ -196,12 +217,14 @@ group :production do
|
|||
gem 'lograge', '~> 0.12'
|
||||
end
|
||||
|
||||
gem 'cocoon', '~> 1.2'
|
||||
gem 'concurrent-ruby', require: false
|
||||
gem 'connection_pool', require: false
|
||||
gem 'xorcist', '~> 1.1'
|
||||
gem 'cocoon', '~> 1.2'
|
||||
|
||||
gem 'net-http', '~> 0.4.0'
|
||||
gem 'rubyzip', '~> 2.3'
|
||||
|
||||
gem 'hcaptcha', '~> 7.1'
|
||||
|
||||
gem 'mail', '~> 2.8'
|
||||
|
|
589
Gemfile.lock
589
Gemfile.lock
File diff suppressed because it is too large
Load diff
76
README.md
76
README.md
|
@ -62,17 +62,17 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre
|
|||
### Tech stack
|
||||
|
||||
- **Ruby on Rails** powers the REST API and other web pages
|
||||
- **React.js** and Redux are used for the dynamic parts of the interface
|
||||
- **React.js** and **Redux** are used for the dynamic parts of the interface
|
||||
- **Node.js** powers the streaming API
|
||||
|
||||
### Requirements
|
||||
|
||||
- **PostgreSQL** 12+
|
||||
- **Redis** 4+
|
||||
- **Ruby** 2.7+
|
||||
- **Node.js** 16+
|
||||
- **Ruby** 3.1+
|
||||
- **Node.js** 18+
|
||||
|
||||
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
|
||||
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, and **Scalingo**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
|
||||
|
||||
## Development
|
||||
|
||||
|
@ -83,45 +83,54 @@ A **Vagrant** configuration is included for development purposes. To use it, com
|
|||
- Install Vagrant and Virtualbox
|
||||
- Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater`
|
||||
- Run `vagrant up`
|
||||
- Run `vagrant ssh -c "cd /vagrant && foreman start"`
|
||||
- Run `vagrant ssh -c "cd /vagrant && bin/dev"`
|
||||
- Open `http://mastodon.local` in your browser
|
||||
|
||||
### MacOS
|
||||
### macOS
|
||||
|
||||
To set up **MacOS** for native development, complete the following steps:
|
||||
To set up **macOS** for native development, complete the following steps:
|
||||
|
||||
- Install the latest stable Ruby version (use a Ruby version manager for easy installation and management of Ruby versions)
|
||||
- Run `brew install postgresql@14`
|
||||
- Run `brew install redis`
|
||||
- Run `brew install imagemagick`
|
||||
- Run `brew install libidn`
|
||||
- Install Foreman or a similar tool (such as [overmind](https://github.com/DarthSim/overmind)) to handle multiple process launching.
|
||||
- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from .nvmrc
|
||||
- Run `corepack enable && corepack prepare`
|
||||
- Run `bundle exec rails db:setup` (optionally prepend `RAILS_ENV=development` to target the dev environment)
|
||||
- Finally, run `overmind start -f Procfile.dev`
|
||||
- Install [Homebrew] and run `brew install postgresql@14 redis imagemagick
|
||||
libidn nvm` to install the required project dependencies
|
||||
- Use a Ruby version manager to activate the ruby in `.ruby-version` and run
|
||||
`nvm use` to activate the node version from `.nvmrc`
|
||||
- Run the `bin/setup` script, which will install the required ruby gems and node
|
||||
packages and prepare the database for local development
|
||||
- Finally, run the `bin/dev` script which will launch services via `overmind`
|
||||
(if installed) or `foreman`
|
||||
|
||||
### Docker
|
||||
|
||||
For development with **Docker**, complete the following steps:
|
||||
For production hosting and deployment with **Docker**, use the `Dockerfile` and
|
||||
`docker-compose.yml` in the project root directory.
|
||||
|
||||
- Install Docker Desktop
|
||||
- Run `docker compose -f .devcontainer/docker-compose.yml up -d`
|
||||
- Run `docker compose -f .devcontainer/docker-compose.yml exec app .devcontainer/post-create.sh`
|
||||
- Finally, run `docker compose -f .devcontainer/docker-compose.yml exec app foreman start -f Procfile.dev`
|
||||
For local development, install and launch [Docker], and run:
|
||||
|
||||
If you are using an IDE with [support for the Development Container specification](https://containers.dev/supporting), it will run the above `docker compose` commands automatically. For **Visual Studio Code** this requires the [Dev Container extension](https://containers.dev/supporting#dev-containers).
|
||||
```shell
|
||||
docker compose -f .devcontainer/compose.yaml up -d
|
||||
docker compose -f .devcontainer/compose.yaml exec app bin/setup
|
||||
docker compose -f .devcontainer/compose.yaml exec app bin/dev
|
||||
```
|
||||
|
||||
### Dev Containers
|
||||
|
||||
Within IDEs that support the [Development Containers] specification, start the
|
||||
"Mastodon on local machine" container from the editor. The necessary `docker
|
||||
compose` commands to build and setup the container should run automatically. For
|
||||
**Visual Studio Code** this requires installing the [Dev Container extension].
|
||||
|
||||
### GitHub Codespaces
|
||||
|
||||
To get you coding in just a few minutes, GitHub Codespaces provides a web-based version of Visual Studio Code and a cloud-hosted development environment fully configured with the software needed for this project..
|
||||
[GitHub Codespaces] provides a web-based version of VS Code and a cloud hosted
|
||||
development environment configured with the software needed for this project.
|
||||
|
||||
- Click this button to create a new codespace:<br>
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json)
|
||||
- Wait for the environment to build. This will take a few minutes.
|
||||
- When the editor is ready, run `foreman start -f Procfile.dev` in the terminal.
|
||||
- After a few seconds, a popup will appear with a button labeled _Open in Browser_. This will open Mastodon.
|
||||
- On the _Ports_ tab, right click on the “stream” row and select _Port visibility_ → _Public_.
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)][codespace]
|
||||
|
||||
- Click the button to create a new codespace, and confirm the options
|
||||
- Wait for the environment to build (takes a few minutes)
|
||||
- When the editor is ready, run `bin/dev` in the terminal
|
||||
- Wait for an _Open in Browser_ prompt. This will open Mastodon
|
||||
- On the _Ports_ tab "stream" setting change _Port visibility_ → _Public_
|
||||
|
||||
## Contributing
|
||||
|
||||
|
@ -140,3 +149,10 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[codespace]: https://codespaces.new/mastodon/mastodon?quickstart=1&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json
|
||||
[Dev Container extension]: https://containers.dev/supporting#dev-containers
|
||||
[Development Containers]: https://containers.dev/supporting
|
||||
[Docker]: https://docs.docker.com
|
||||
[GitHub Codespaces]: https://docs.github.com/en/codespaces
|
||||
[Homebrew]: https://brew.sh
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can either:
|
||||
|
||||
- open a [Github security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new)
|
||||
- open a [GitHub security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new)
|
||||
- reach us at <security@joinmastodon.org>
|
||||
|
||||
You should _not_ report such issues on public GitHub issues or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk.
|
||||
|
|
9
Vagrantfile
vendored
9
Vagrantfile
vendored
|
@ -151,6 +151,12 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||
vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
|
||||
end
|
||||
|
||||
config.vm.provider :libvirt do |libvirt|
|
||||
libvirt.cpus = 3
|
||||
libvirt.memory = 8192
|
||||
end
|
||||
|
||||
|
||||
# This uses the vagrant-hostsupdater plugin, and lets you
|
||||
# access the development site at http://mastodon.local.
|
||||
# If you change it, also change it in .env.vagrant before provisioning
|
||||
|
@ -173,6 +179,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||
|
||||
# Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080
|
||||
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
||||
config.vm.network :forwarded_port, guest: 3035, host: 3035
|
||||
config.vm.network :forwarded_port, guest: 4000, host: 4000
|
||||
config.vm.network :forwarded_port, guest: 8080, host: 8080
|
||||
config.vm.network :forwarded_port, guest: 9200, host: 9200
|
||||
|
@ -188,7 +195,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||
|
||||
config.vm.post_up_message = <<MESSAGE
|
||||
To start server
|
||||
$ vagrant ssh -c "cd /vagrant && foreman start"
|
||||
$ vagrant ssh -c "cd /vagrant && bin/dev"
|
||||
MESSAGE
|
||||
|
||||
end
|
||||
|
|
|
@ -25,7 +25,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE
|
||||
@statuses = filtered_statuses.without_reblogs.limit(limit)
|
||||
@statuses = cache_collection(@statuses, Status)
|
||||
@statuses = preload_collection(@statuses, Status)
|
||||
end
|
||||
|
||||
format.json do
|
||||
|
@ -46,7 +46,7 @@ class AccountsController < ApplicationController
|
|||
end
|
||||
|
||||
def default_statuses
|
||||
@account.statuses.where(visibility: [:public, :unlisted])
|
||||
@account.statuses.distributable_visibility
|
||||
end
|
||||
|
||||
def only_media_scope
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::BaseController < Api::BaseController
|
||||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
skip_before_action :require_authenticated_user!
|
||||
skip_before_action :require_not_suspended!
|
||||
skip_around_action :set_locale
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::ClaimsController < ActivityPub::BaseController
|
||||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
before_action :require_account_signature!
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::CollectionsController < ActivityPub::BaseController
|
||||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
|
@ -21,7 +18,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
def set_items
|
||||
case params[:id]
|
||||
when 'featured'
|
||||
@items = for_signed_account { cache_collection(@account.pinned_statuses, Status) }
|
||||
@items = for_signed_account { preload_collection(@account.pinned_statuses, Status) }
|
||||
@items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) }
|
||||
when 'tags'
|
||||
@items = for_signed_account { @account.featured_tags }
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
@ -63,7 +60,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
def set_statuses
|
||||
return unless page_requested?
|
||||
|
||||
@statuses = cache_collection_paginated_by_id(
|
||||
@statuses = preload_collection_paginated_by_id(
|
||||
AccountStatusesFilter.new(@account, signed_request_account).results,
|
||||
Status,
|
||||
LIMIT,
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::RepliesController < ActivityPub::BaseController
|
||||
include SignatureVerification
|
||||
include Authorization
|
||||
include AccountOwnedConcern
|
||||
|
||||
DESCENDANTS_LIMIT = 60
|
||||
|
||||
|
@ -33,7 +31,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
|||
|
||||
def set_replies
|
||||
@replies = only_other_accounts? ? Status.where.not(account_id: @account.id).joins(:account).merge(Account.without_suspended) : @account.statuses
|
||||
@replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
|
||||
@replies = @replies.distributable_visibility.where(in_reply_to_id: @status.id)
|
||||
@replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
|
||||
end
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ class Admin::DomainAllowsController < Admin::BaseController
|
|||
def destroy
|
||||
authorize @domain_allow, :destroy?
|
||||
UnallowDomainService.new.call(@domain_allow)
|
||||
log_action :destroy, @domain_allow
|
||||
|
||||
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,18 @@ module Admin
|
|||
class DomainBlocksController < BaseController
|
||||
before_action :set_domain_block, only: [:destroy, :edit, :update]
|
||||
|
||||
PERMITTED_PARAMS = %i(
|
||||
domain
|
||||
obfuscate
|
||||
private_comment
|
||||
public_comment
|
||||
reject_media
|
||||
reject_reports
|
||||
severity
|
||||
).freeze
|
||||
|
||||
PERMITTED_UPDATE_PARAMS = PERMITTED_PARAMS.without(:domain).freeze
|
||||
|
||||
def batch
|
||||
authorize :domain_block, :create?
|
||||
@form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||
|
@ -88,11 +100,17 @@ module Admin
|
|||
end
|
||||
|
||||
def update_params
|
||||
params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||
params
|
||||
.require(:domain_block)
|
||||
.slice(*PERMITTED_UPDATE_PARAMS)
|
||||
.permit(*PERMITTED_UPDATE_PARAMS)
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||
params
|
||||
.require(:domain_block)
|
||||
.slice(*PERMITTED_PARAMS)
|
||||
.permit(*PERMITTED_PARAMS)
|
||||
end
|
||||
|
||||
def form_domain_block_batch_params
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,7 +9,7 @@ module Admin
|
|||
|
||||
@site_upload.destroy!
|
||||
|
||||
redirect_to admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg')
|
||||
redirect_back fallback_location: admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg')
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -8,6 +8,8 @@ class Api::BaseController < ApplicationController
|
|||
include Api::AccessTokenTrackingConcern
|
||||
include Api::CachingConcern
|
||||
include Api::ContentSecurityPolicy
|
||||
include Api::ErrorHandling
|
||||
include Api::Pagination
|
||||
|
||||
skip_before_action :require_functional!, unless: :limited_federation_mode?
|
||||
|
||||
|
@ -18,51 +20,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,13 +30,6 @@ class Api::BaseController < ApplicationController
|
|||
|
||||
protected
|
||||
|
||||
def set_pagination_headers(next_path = nil, prev_path = nil)
|
||||
links = []
|
||||
links << [next_path, [%w(rel next)]] if next_path
|
||||
links << [prev_path, [%w(rel prev)]] if prev_path
|
||||
response.headers['Link'] = LinkHeader.new(links) unless links.empty?
|
||||
end
|
||||
|
||||
def limit_param(default_limit)
|
||||
return default_limit unless params[:limit]
|
||||
|
||||
|
@ -108,10 +58,6 @@ class Api::BaseController < ApplicationController
|
|||
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
|
||||
end
|
||||
|
||||
def require_valid_pagination_options!
|
||||
render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid?
|
||||
end
|
||||
|
||||
def require_user!
|
||||
if !current_user
|
||||
render json: { error: 'This method requires an authenticated user' }, status: 422
|
||||
|
@ -140,10 +86,6 @@ class Api::BaseController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def pagination_options_invalid?
|
||||
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
|
||||
end
|
||||
|
||||
def respond_with_error(code)
|
||||
render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::CredentialsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, except: [:update]
|
||||
before_action -> { doorkeeper_authorize! :profile, :read, :'read:accounts' }, except: [:update]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update]
|
||||
before_action :require_user!
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -64,8 +60,4 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
|
|||
def records_continue?
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
@ -64,8 +60,4 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
|
|||
def records_continue?
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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!
|
||||
|
@ -19,11 +19,11 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
|||
end
|
||||
|
||||
def load_statuses
|
||||
@account.unavailable? ? [] : cached_account_statuses
|
||||
@account.unavailable? ? [] : preloaded_account_statuses
|
||||
end
|
||||
|
||||
def cached_account_statuses
|
||||
cache_collection_paginated_by_id(
|
||||
def preloaded_account_statuses
|
||||
preload_collection_paginated_by_id(
|
||||
AccountStatusesFilter.new(@account, current_account, params).results,
|
||||
Status,
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
|
@ -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
|
||||
|
|
|
@ -9,16 +9,22 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }, only: [:block, :unblock]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create]
|
||||
|
||||
before_action :require_user!, except: [:show, :create]
|
||||
before_action :set_account, except: [:create]
|
||||
before_action :check_account_approval, except: [:create]
|
||||
before_action :check_account_confirmation, except: [:create]
|
||||
before_action :require_user!, except: [:index, :show, :create]
|
||||
before_action :set_account, except: [:index, :create]
|
||||
before_action :set_accounts, only: [:index]
|
||||
before_action :check_account_approval, except: [:index, :create]
|
||||
before_action :check_account_confirmation, except: [:index, :create]
|
||||
before_action :check_enabled_registrations, only: [:create]
|
||||
before_action :check_accounts_limit, only: [:index]
|
||||
|
||||
skip_before_action :require_authenticated_user!, only: :create
|
||||
|
||||
override_rate_limit_headers :follow, family: :follows
|
||||
|
||||
def index
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @account, serializer: REST::AccountSerializer
|
||||
|
@ -79,6 +85,10 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
@account = Account.find(params[:id])
|
||||
end
|
||||
|
||||
def set_accounts
|
||||
@accounts = Account.where(id: account_ids).without_unapproved
|
||||
end
|
||||
|
||||
def check_account_approval
|
||||
raise(ActiveRecord::RecordNotFound) if @account.local? && @account.user_pending?
|
||||
end
|
||||
|
@ -87,10 +97,22 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
raise(ActiveRecord::RecordNotFound) if @account.local? && !@account.user_confirmed?
|
||||
end
|
||||
|
||||
def check_accounts_limit
|
||||
raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT
|
||||
end
|
||||
|
||||
def relationships(**options)
|
||||
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
|
||||
end
|
||||
|
||||
def account_ids
|
||||
Array(accounts_params[:id]).uniq.map(&:to_i)
|
||||
end
|
||||
|
||||
def accounts_params
|
||||
params.permit(id: [])
|
||||
end
|
||||
|
||||
def account_params
|
||||
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code)
|
||||
end
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -16,8 +16,6 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController
|
|||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
def index
|
||||
authorize :canonical_email_block, :index?
|
||||
render json: @canonical_email_blocks, each_serializer: REST::Admin::CanonicalEmailBlockSerializer
|
||||
|
@ -65,10 +63,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,19 +71,11 @@ 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?
|
||||
@canonical_email_blocks.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,8 +14,6 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
|||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
def index
|
||||
authorize :domain_allow, :index?
|
||||
render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer
|
||||
|
@ -61,10 +59,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,22 +67,14 @@ 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?
|
||||
@domain_allows.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(:domain)
|
||||
end
|
||||
|
|
|
@ -14,8 +14,6 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
|||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
def index
|
||||
authorize :domain_block, :index?
|
||||
render json: @domain_blocks, each_serializer: REST::Admin::DomainBlockSerializer
|
||||
|
@ -29,10 +27,11 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
|||
def create
|
||||
authorize :domain_block, :create?
|
||||
|
||||
@domain_block = DomainBlock.new(resource_params)
|
||||
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
|
||||
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present?
|
||||
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if conflicts_with_existing_block?(@domain_block, existing_domain_block)
|
||||
|
||||
@domain_block = DomainBlock.create!(resource_params)
|
||||
@domain_block.save!
|
||||
DomainBlockWorker.perform_async(@domain_block.id)
|
||||
log_action :create, @domain_block
|
||||
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
|
||||
|
@ -55,6 +54,10 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
|||
|
||||
private
|
||||
|
||||
def conflicts_with_existing_block?(domain_block, existing_domain_block)
|
||||
existing_domain_block.present? && (existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain) || !domain_block.stricter_than?(existing_domain_block))
|
||||
end
|
||||
|
||||
def set_domain_blocks
|
||||
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||
end
|
||||
|
@ -72,10 +75,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,22 +83,14 @@ 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?
|
||||
@domain_blocks.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||
end
|
||||
|
|
|
@ -14,10 +14,6 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
|
|||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(
|
||||
limit
|
||||
).freeze
|
||||
|
||||
def index
|
||||
authorize :email_domain_block, :index?
|
||||
render json: @email_domain_blocks, each_serializer: REST::Admin::EmailDomainBlockSerializer
|
||||
|
@ -58,10 +54,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,19 +62,11 @@ 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?
|
||||
@email_domain_blocks.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,10 +14,6 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
|
|||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(
|
||||
limit
|
||||
).freeze
|
||||
|
||||
def index
|
||||
authorize :ip_block, :index?
|
||||
render json: @ip_blocks, each_serializer: REST::Admin::IpBlockSerializer
|
||||
|
@ -63,10 +59,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,19 +67,11 @@ 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?
|
||||
@ip_blocks.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -12,7 +12,13 @@ class Api::V1::Admin::TagsController < Api::BaseController
|
|||
after_action :verify_authorized
|
||||
|
||||
LIMIT = 100
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
PERMITTED_PARAMS = %i(
|
||||
display_name
|
||||
listable
|
||||
trendable
|
||||
usable
|
||||
).freeze
|
||||
|
||||
def index
|
||||
authorize :tag, :index?
|
||||
|
@ -41,11 +47,9 @@ class Api::V1::Admin::TagsController < Api::BaseController
|
|||
end
|
||||
|
||||
def tag_params
|
||||
params.permit(:display_name, :trendable, :usable, :listable)
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
params
|
||||
.slice(*PERMITTED_PARAMS)
|
||||
.permit(*PERMITTED_PARAMS)
|
||||
end
|
||||
|
||||
def next_path
|
||||
|
@ -56,19 +60,11 @@ 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?
|
||||
@tags.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,6 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC
|
|||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
def index
|
||||
authorize :preview_card_provider, :index?
|
||||
|
||||
|
@ -42,10 +40,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,19 +48,11 @@ 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?
|
||||
@providers.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,6 @@ class Api::V1::Apps::CredentialsController < Api::BaseController
|
|||
def show
|
||||
return doorkeeper_render_error unless valid_doorkeeper_token?
|
||||
|
||||
render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer, fields: %i(name website vapid_key client_id scopes)
|
||||
render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class Api::V1::AppsController < Api::BaseController
|
|||
|
||||
def create
|
||||
@app = Doorkeeper::Application.create!(application_options)
|
||||
render json: @app, serializer: REST::ApplicationSerializer
|
||||
render json: @app, serializer: REST::CredentialApplicationSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -24,6 +24,6 @@ class Api::V1::AppsController < Api::BaseController
|
|||
end
|
||||
|
||||
def app_params
|
||||
params.permit(:client_name, :redirect_uris, :scopes, :website)
|
||||
params.permit(:client_name, :scopes, :website, :redirect_uris, redirect_uris: [])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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,19 +36,11 @@ 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?
|
||||
paginated_blocks.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,11 +13,11 @@ class Api::V1::BookmarksController < Api::BaseController
|
|||
private
|
||||
|
||||
def load_statuses
|
||||
cached_bookmarks
|
||||
preloaded_bookmarks
|
||||
end
|
||||
|
||||
def cached_bookmarks
|
||||
cache_collection(results.map(&:status), Status)
|
||||
def preloaded_bookmarks
|
||||
preload_collection(results.map(&:status), Status)
|
||||
end
|
||||
|
||||
def results
|
||||
|
@ -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,19 +39,11 @@ 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?
|
||||
results.size == limit_param(DEFAULT_STATUSES_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,25 +38,21 @@ class Api::V1::ConversationsController < Api::BaseController
|
|||
def paginated_conversations
|
||||
AccountConversation.where(account: current_account)
|
||||
.includes(
|
||||
account: :account_stat,
|
||||
account: [:account_stat, user: :role],
|
||||
last_status: [
|
||||
:media_attachments,
|
||||
:status_stat,
|
||||
:tags,
|
||||
{
|
||||
preview_cards_status: :preview_card,
|
||||
active_mentions: [account: :account_stat],
|
||||
account: :account_stat,
|
||||
preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } },
|
||||
active_mentions: :account,
|
||||
account: [:account_stat, user: :role],
|
||||
},
|
||||
]
|
||||
)
|
||||
.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
|
||||
|
@ -76,8 +72,4 @@ class Api::V1::ConversationsController < Api::BaseController
|
|||
def records_continue?
|
||||
@conversations.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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,19 +37,11 @@ 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?
|
||||
@encrypted_messages.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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,22 +46,14 @@ 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?
|
||||
@blocks.size == limit_param(BLOCK_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def domain_block_params
|
||||
params.permit(:domain)
|
||||
end
|
||||
|
|
|
@ -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,22 +40,14 @@ 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?
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def unlimited?
|
||||
params[:limit] == '0'
|
||||
end
|
||||
|
|
|
@ -13,11 +13,11 @@ class Api::V1::FavouritesController < Api::BaseController
|
|||
private
|
||||
|
||||
def load_statuses
|
||||
cached_favourites
|
||||
preloaded_favourites
|
||||
end
|
||||
|
||||
def cached_favourites
|
||||
cache_collection(results.map(&:status), Status)
|
||||
def preloaded_favourites
|
||||
preload_collection(results.map(&:status), Status)
|
||||
end
|
||||
|
||||
def results
|
||||
|
@ -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,19 +39,11 @@ 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?
|
||||
results.size == limit_param(DEFAULT_STATUSES_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,6 +12,6 @@ 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.suggestions_for_account(current_account).limit(10)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
@ -71,8 +67,4 @@ class Api::V1::FollowRequestsController < Api::BaseController
|
|||
def records_continue?
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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,19 +30,11 @@ 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?
|
||||
@results.size == limit_param(TAGS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(:limit).permit(:limit).merge(core_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class Api::V1::Instances::ExtendedDescriptionsController < Api::V1::Instances::B
|
|||
|
||||
before_action :set_extended_description
|
||||
|
||||
# Override `current_user` to avoid reading session cookies unless in whitelist mode
|
||||
# Override `current_user` to avoid reading session cookies unless in limited federation mode
|
||||
def current_user
|
||||
super if limited_federation_mode?
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class Api::V1::Instances::PeersController < Api::V1::Instances::BaseController
|
|||
|
||||
skip_around_action :set_locale
|
||||
|
||||
# Override `current_user` to avoid reading session cookies unless in whitelist mode
|
||||
# Override `current_user` to avoid reading session cookies unless in limited federation mode
|
||||
def current_user
|
||||
super if limited_federation_mode?
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ class Api::V1::Instances::RulesController < Api::V1::Instances::BaseController
|
|||
|
||||
before_action :set_rules
|
||||
|
||||
# Override `current_user` to avoid reading session cookies unless in whitelist mode
|
||||
# Override `current_user` to avoid reading session cookies unless in limited federation mode
|
||||
def current_user
|
||||
super if limited_federation_mode?
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue