Merge branch 'upstream' into main
This commit is contained in:
commit
ec7bc4ea5f
|
@ -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.
|
||||
|
||||
🔍 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.
|
||||
|
|
|
@ -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': 'warn',
|
||||
// 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',
|
||||
|
@ -355,7 +330,6 @@ module.exports = defineConfig({
|
|||
'plugin:import/typescript',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:jsdoc/recommended-typescript',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
|
@ -364,6 +338,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'],
|
||||
|
@ -378,6 +358,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
|
||||
|
|
|
@ -23,7 +23,7 @@ runs:
|
|||
shell: bash
|
||||
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/cache@v3
|
||||
- uses: actions/cache@v4
|
||||
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
|
||||
with:
|
||||
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
@ -59,7 +60,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 +126,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'] },
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -53,19 +53,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
|
||||
|
|
|
@ -5,13 +5,13 @@ on:
|
|||
branches:
|
||||
- main
|
||||
paths:
|
||||
- crowdin.yml
|
||||
- app/javascript/mastodon/locales/en.json
|
||||
- config/locales/en.yml
|
||||
- config/locales/simple_form.en.yml
|
||||
- config/locales/activerecord.en.yml
|
||||
- config/locales/devise.en.yml
|
||||
- config/locales/doorkeeper.en.yml
|
||||
- crowdin-glitch.yml
|
||||
- app/javascript/flavours/glitch/locales/en.json
|
||||
- config/locales-glitch/en.yml
|
||||
- config/locales-glitch/simple_form.en.yml
|
||||
- config/locales-glitch/activerecord.en.yml
|
||||
- config/locales-glitch/devise.en.yml
|
||||
- config/locales-glitch/doorkeeper.en.yml
|
||||
- .github/workflows/crowdin-upload.yml
|
||||
|
||||
jobs:
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 }}'
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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,18 +129,109 @@ 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:setup
|
||||
bin/flatware fan bin/rails db:test:prepare
|
||||
|
||||
- run: bin/flatware rspec -r ./spec/flatware_helper.rb
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: matrix.ruby-version == '.ruby-version'
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: coverage/lcov/*.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
|
||||
- run: bin/rspec --tag paperclip_processing
|
||||
|
||||
- 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-e2e:
|
||||
name: End to End testing
|
||||
|
@ -158,9 +248,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 +258,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 +271,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 +287,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 +306,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 +320,7 @@ jobs:
|
|||
if: failure()
|
||||
with:
|
||||
name: e2e-screenshots
|
||||
path: tmp/screenshots/
|
||||
path: tmp/capybara/
|
||||
|
||||
test-search:
|
||||
name: Elastic Search integration testing
|
||||
|
@ -241,9 +337,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 +347,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 +395,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 +440,4 @@ jobs:
|
|||
if: failure()
|
||||
with:
|
||||
name: test-search-screenshots
|
||||
path: tmp/screenshots/
|
||||
path: tmp/capybara/
|
||||
|
|
|
@ -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/
|
|
@ -54,6 +54,13 @@
|
|||
# Ignore Docker option files
|
||||
docker-compose.override.yml
|
||||
|
||||
# Ignore public
|
||||
/public/assets
|
||||
/public/emoji
|
||||
/public/packs
|
||||
/public/packs-test
|
||||
/public/system
|
||||
|
||||
# Ignore emoji map file
|
||||
/app/javascript/mastodon/features/emoji/emoji_map.json
|
||||
|
||||
|
@ -74,6 +81,7 @@ app/javascript/styles/mastodon/reset.scss
|
|||
# Ignore the generated AUTHORS.md
|
||||
AUTHORS.md
|
||||
|
||||
# Process a few selected JS files
|
||||
!lint-staged.config.js
|
||||
|
||||
# Ignore glitch-soc emoji map file
|
||||
|
|
241
.rubocop.yml
241
.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,219 +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 `tootctl` CLI code and in boot ENV checker
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
|
||||
Rails/Exit:
|
||||
Exclude:
|
||||
- 'config/boot.rb'
|
||||
- 'lib/mastodon/cli/*.rb'
|
||||
|
||||
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
|
||||
Rails/LexicallyScopedActionFilter:
|
||||
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: 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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
require:
|
||||
- ../lib/linter/rubocop_middle_dot
|
||||
|
||||
Style/MiddleDot:
|
||||
Enabled: true
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
Layout/FirstHashElementIndentation:
|
||||
EnforcedStyle: consistent
|
||||
|
||||
Layout/LineLength:
|
||||
Max: 300 # Default of 120 causes a duplicate entry in generated todo 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
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
Naming/BlockForwarding:
|
||||
EnforcedStyle: explicit
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
Rails/BulkChangeTable:
|
||||
Enabled: false # Conflicts with strong_migrations features
|
||||
|
||||
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
|
|
@ -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
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
RSpecRails/HttpStatus:
|
||||
EnforcedStyle: numeric
|
|
@ -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: []
|
|
@ -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
|
86
CHANGELOG.md
86
CHANGELOG.md
|
@ -2,6 +2,92 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.2.10] - 2024-07-04
|
||||
|
||||
### Security
|
||||
|
||||
- Fix incorrect permission checking on multiple API endpoints ([GHSA-58x8-3qxw-6hm7](https://github.com/mastodon/mastodon/security/advisories/GHSA-58x8-3qxw-6hm7))
|
||||
- Fix incorrect authorship checking when processing some activities (CVE-2024-37903, [GHSA-xjvf-fm67-4qc3](https://github.com/mastodon/mastodon/security/advisories/GHSA-xjvf-fm67-4qc3))
|
||||
- Fix ongoing streaming sessions not being invalidated when application tokens get revoked ([GHSA-vp5r-5pgw-jwqx](https://github.com/mastodon/mastodon/security/advisories/GHSA-vp5r-5pgw-jwqx))
|
||||
- Update dependencies
|
||||
|
||||
### Added
|
||||
|
||||
- Add yarn version specification to avoid confusion with Yarn 3 and Yarn 4
|
||||
|
||||
### Changed
|
||||
|
||||
- Change preview cards generation to skip unusually long URLs ([oneiros](https://github.com/mastodon/mastodon/pull/30854))
|
||||
- Change search modifiers to be case-insensitive ([Gargron](https://github.com/mastodon/mastodon/pull/30865))
|
||||
- Change `STATSD_ADDR` handling to emit a warning rather than crashing if the address is unreachable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30691))
|
||||
- Change PWA start URL from `/home` to `/` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27377))
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed dependency on `posix-spawn` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18559))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix scheduled statuses scheduled in less than 5 minutes being immediately published ([danielmbrasil](https://github.com/mastodon/mastodon/pull/30584))
|
||||
- Fix encoding detection for link cards ([oneiros](https://github.com/mastodon/mastodon/pull/30780))
|
||||
- Fix `/admin/accounts/:account_id/statuses/:id` for edited posts with media attachments ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30819))
|
||||
- Fix duplicate `@context` attribute in user archive export ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30653))
|
||||
|
||||
## [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
|
||||
|
|
194
Dockerfile
194
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)
|
||||
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
|
||||
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.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 \
|
||||
|
@ -113,7 +117,7 @@ RUN \
|
|||
;
|
||||
|
||||
# Create temporary build layer from base image
|
||||
FROM ruby as build
|
||||
FROM ruby AS build
|
||||
|
||||
# Copy Node package configuration files into working directory
|
||||
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
||||
|
@ -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,8 +184,70 @@ 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
|
||||
FROM build AS bundler
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
|
@ -174,7 +269,7 @@ RUN \
|
|||
bundle install -j"$(nproc)";
|
||||
|
||||
# Create temporary node specific build layer from build layer
|
||||
FROM build as yarn
|
||||
FROM build AS yarn
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
|
@ -191,7 +286,7 @@ RUN \
|
|||
yarn workspaces focus --production @mastodon/mastodon;
|
||||
|
||||
# Create temporary assets build layer from build layer
|
||||
FROM build as precompiler
|
||||
FROM build AS precompiler
|
||||
|
||||
# Copy Mastodon sources into precompiler layer
|
||||
COPY . /opt/mastodon/
|
||||
|
@ -200,17 +295,22 @@ 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;
|
||||
|
||||
# Prep final Mastodon Ruby layer
|
||||
FROM ruby as mastodon
|
||||
FROM ruby AS mastodon
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
|
@ -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,6 +369,19 @@ 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 \
|
||||
ldconfig; \
|
||||
# Smoketest media processors
|
||||
vips -v; \
|
||||
ffmpeg -version; \
|
||||
ffprobe -version;
|
||||
|
||||
RUN \
|
||||
# Precompile bootsnap code for faster Rails startup
|
||||
|
|
99
Gemfile
99
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.18.0', require: false
|
||||
gem 'browser'
|
||||
gem 'browser', '< 6' # https://github.com/fnando/browser/issues/543
|
||||
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,56 +51,79 @@ 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'
|
||||
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'
|
||||
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.31.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
|
||||
# Enable usage of all available CPUs/cores during spec runs
|
||||
gem 'flatware-rspec'
|
||||
|
||||
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
|
||||
gem 'rspec-github', '~> 2.4', require: false
|
||||
|
||||
|
@ -112,8 +133,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'
|
||||
|
@ -125,12 +146,6 @@ group :test do
|
|||
# Used to mock environment variables
|
||||
gem 'climate_control'
|
||||
|
||||
# Generating fake data for specs
|
||||
gem 'faker', '~> 3.2'
|
||||
|
||||
# Generate test objects for specs
|
||||
gem 'fabrication', '~> 2.30'
|
||||
|
||||
# Add back helpers functions removed in Rails 5.1
|
||||
gem 'rails-controller-testing', '~> 1.0'
|
||||
|
||||
|
@ -155,6 +170,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'
|
||||
|
@ -165,7 +181,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
|
||||
|
@ -182,6 +198,12 @@ group :development, :test do
|
|||
# Interactive Debugging tools
|
||||
gem 'debug', '~> 1.8'
|
||||
|
||||
# Generate fake data values
|
||||
gem 'faker', '~> 3.2'
|
||||
|
||||
# Generate factory objects
|
||||
gem 'fabrication', '~> 2.30'
|
||||
|
||||
# Profiling tools
|
||||
gem 'memory_profiler', require: false
|
||||
gem 'ruby-prof', require: false
|
||||
|
@ -196,13 +218,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'
|
||||
|
|
578
Gemfile.lock
578
Gemfile.lock
File diff suppressed because it is too large
Load Diff
172
README.md
172
README.md
|
@ -1,14 +1,174 @@
|
|||
# Mastodon Glitch Edition
|
||||
|
||||
> Now with automated deploys!
|
||||
[![Ruby Testing](https://github.com/glitch-soc/mastodon/actions/workflows/test-ruby.yml/badge.svg)](https://github.com/glitch-soc/mastodon/actions/workflows/test-ruby.yml)
|
||||
[![Crowdin](https://badges.crowdin.net/glitch-soc/localized.svg)][glitch-crowdin]
|
||||
|
||||
[![Build Status](https://img.shields.io/circleci/project/github/glitch-soc/mastodon.svg)][circleci]
|
||||
[![Code Climate](https://img.shields.io/codeclimate/maintainability/glitch-soc/mastodon.svg)][code_climate]
|
||||
|
||||
[circleci]: https://circleci.com/gh/glitch-soc/mastodon
|
||||
[code_climate]: https://codeclimate.com/github/glitch-soc/mastodon
|
||||
[glitch-crowdin]: https://crowdin.com/project/glitch-soc
|
||||
|
||||
So here's the deal: we all work on this code, and anyone who uses that does so absolutely at their own risk. can you dig it?
|
||||
|
||||
- You can view documentation for this project at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/).
|
||||
- And contributing guidelines are available [here](CONTRIBUTING.md) and [here](https://glitch-soc.github.io/docs/contributing/).
|
||||
|
||||
Mastodon Glitch Edition is a fork of [Mastodon](https://github.com/mastodon/mastodon). Upstream's README file is reproduced below.
|
||||
|
||||
---
|
||||
|
||||
<h1><picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="./lib/assets/wordmark.dark.png?raw=true">
|
||||
<source media="(prefers-color-scheme: light)" srcset="./lib/assets/wordmark.light.png?raw=true">
|
||||
<img alt="Mastodon" src="./lib/assets/wordmark.light.png?raw=true" height="34">
|
||||
</picture></h1>
|
||||
|
||||
[![GitHub release](https://img.shields.io/github/release/mastodon/mastodon.svg)][releases]
|
||||
[![Ruby Testing](https://github.com/mastodon/mastodon/actions/workflows/test-ruby.yml/badge.svg)](https://github.com/mastodon/mastodon/actions/workflows/test-ruby.yml)
|
||||
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin]
|
||||
|
||||
[releases]: https://github.com/mastodon/mastodon/releases
|
||||
[crowdin]: https://crowdin.com/project/mastodon
|
||||
|
||||
Mastodon is a **free, open-source social network server** based on ActivityPub where users can follow friends and discover new ones. On Mastodon, users can publish anything they want: links, pictures, text, and video. All Mastodon servers are interoperable as a federated network (users on one server can seamlessly communicate with users from another one, including non-Mastodon software that implements ActivityPub!)
|
||||
|
||||
Click below to **learn more** in a video:
|
||||
|
||||
[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo]
|
||||
|
||||
[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
|
||||
|
||||
## Navigation
|
||||
|
||||
- [Project homepage 🐘](https://joinmastodon.org)
|
||||
- [Support the development via Patreon][patreon]
|
||||
- [View sponsors](https://joinmastodon.org/sponsors)
|
||||
- [Blog](https://blog.joinmastodon.org)
|
||||
- [Documentation](https://docs.joinmastodon.org)
|
||||
- [Roadmap](https://joinmastodon.org/roadmap)
|
||||
- [Official Docker image](https://github.com/mastodon/mastodon/pkgs/container/mastodon)
|
||||
- [Browse Mastodon servers](https://joinmastodon.org/communities)
|
||||
- [Browse Mastodon apps](https://joinmastodon.org/apps)
|
||||
|
||||
[patreon]: https://www.patreon.com/mastodon
|
||||
|
||||
## Features
|
||||
|
||||
<img src="/app/javascript/images/elephant_ui_working.svg?raw=true" align="right" width="30%" />
|
||||
|
||||
### No vendor lock-in: Fully interoperable with any conforming platform
|
||||
|
||||
It doesn't have to be Mastodon; whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/)
|
||||
|
||||
### Real-time, chronological timeline updates
|
||||
|
||||
Updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!
|
||||
|
||||
### Media attachments like images and short videos
|
||||
|
||||
Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos loop continuously!
|
||||
|
||||
### Safety and moderation tools
|
||||
|
||||
Mastodon includes private posts, locked accounts, phrase filtering, muting, blocking, and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/)
|
||||
|
||||
### OAuth2 and a straightforward REST API
|
||||
|
||||
Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Streaming APIs. This results in a rich app ecosystem with a lot of choices!
|
||||
|
||||
## Deployment
|
||||
|
||||
### 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
|
||||
- **Node.js** powers the streaming API
|
||||
|
||||
### Requirements
|
||||
|
||||
- **PostgreSQL** 12+
|
||||
- **Redis** 4+
|
||||
- **Ruby** 3.1+
|
||||
- **Node.js** 18+
|
||||
|
||||
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
|
||||
|
||||
### Vagrant
|
||||
|
||||
A **Vagrant** configuration is included for development purposes. To use it, complete the following steps:
|
||||
|
||||
- Install Vagrant and Virtualbox
|
||||
- Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater`
|
||||
- Run `vagrant up`
|
||||
- Run `vagrant ssh -c "cd /vagrant && bin/dev"`
|
||||
- Open `http://mastodon.local` in your browser
|
||||
|
||||
### macOS
|
||||
|
||||
To set up **macOS** for native development, complete the following steps:
|
||||
|
||||
- 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 production hosting and deployment with **Docker**, use the `Dockerfile` and
|
||||
`docker-compose.yml` in the project root directory.
|
||||
|
||||
For local development, install and launch [Docker], and run:
|
||||
|
||||
```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
|
||||
|
||||
[GitHub Codespaces] provides a web-based version of VS Code and a cloud hosted
|
||||
development environment configured with the software needed for this project.
|
||||
|
||||
[![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
|
||||
|
||||
Mastodon is **free, open-source software** licensed under **AGPLv3**.
|
||||
|
||||
You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository or submit translations using Crowdin. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md). If your contributions are accepted into Mastodon, you can request to be paid through [our OpenCollective](https://opencollective.com/mastodon).
|
||||
|
||||
**IRC channel**: #mastodon on irc.libera.chat
|
||||
|
||||
## License
|
||||
|
||||
Copyright (C) 2016-2024 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md))
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
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.
|
||||
|
|
|
@ -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.not_local_only.where(visibility: [:public, :unlisted])
|
||||
@account.statuses.not_local_only.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.not_local_only, Status) }
|
||||
@items = for_signed_account { preload_collection(@account.pinned_statuses.not_local_only, 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
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ module Admin
|
|||
|
||||
layout 'admin'
|
||||
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
|
@ -19,10 +18,6 @@ module Admin
|
|||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
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
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue