Compare commits
81 commits
paravielfa
...
stable-3.3
Author | SHA1 | Date | |
---|---|---|---|
|
d83a46735c | ||
|
a73f32f7dc | ||
|
637c7d464b | ||
|
aeccbb2a14 | ||
|
b99c58b6fe | ||
|
d7adbf5a63 | ||
|
5231ae7ae6 | ||
|
1cc5c35bb0 | ||
|
f22f6d970d | ||
|
5efc927261 | ||
|
5e9118c9bb | ||
|
b8a5b3a3db | ||
|
b84182b5ba | ||
|
0842e3b4fb | ||
|
e8a2d12338 | ||
|
df6a953f52 | ||
|
c2bd6e90b4 | ||
|
7619689fcb | ||
|
5ec943f85d | ||
|
ad06423e71 | ||
|
82a490ac7f | ||
|
dbe5e29e38 | ||
|
ff19501e50 | ||
|
e02a7cfeb2 | ||
|
5d72e6c4d0 | ||
|
b6b19419e2 | ||
|
a19aec0f48 | ||
|
1ddbefb787 | ||
|
85c845c001 | ||
|
80ca4fdb3c | ||
|
168272fe61 | ||
|
2c02cb59ef | ||
|
edc55002cf | ||
|
e10920eb20 | ||
|
d33b361000 | ||
|
5b07f4e90e | ||
|
0994c4b11a | ||
|
d2cdfe92ed | ||
|
6c344d90c7 | ||
|
c0b2c2c166 | ||
|
19edb7a3f4 | ||
|
53e4efd07d | ||
|
3f882c2c17 | ||
|
1cfa2bdb03 | ||
|
1b32c001bc | ||
|
31d9aa8ed0 | ||
|
4d41c91335 | ||
|
678e0ad419 | ||
|
c89809afc5 | ||
|
a319fd3cc4 | ||
|
24dee67d32 | ||
|
07042a0913 | ||
|
4978d387ee | ||
|
0951c691ff | ||
|
fc4b9856f8 | ||
|
add7b9f82e | ||
|
9437e9f0b9 | ||
|
0fe57a9140 | ||
|
3a4d9f1f2d | ||
|
78d5bda973 | ||
|
4b025cf7e6 | ||
|
4bd8dc09d8 | ||
|
3799fd17ba | ||
|
53814b2b31 | ||
|
2012c5ae50 | ||
|
9aa7286c8f | ||
|
4b9a0cfe5e | ||
|
b593a7da8c | ||
|
48b25e457d | ||
|
da14725a96 | ||
|
cc21670b3c | ||
|
685cde55cb | ||
|
a2dc4e583b | ||
|
13d1111a92 | ||
|
6386421d1a | ||
|
4063bbe04e | ||
|
4ea2c1da95 | ||
|
47cab05003 | ||
|
02d195809b | ||
|
64d9b84f1d | ||
|
a6e9c41ed4 |
4679 changed files with 129922 additions and 278909 deletions
|
@ -1,7 +0,0 @@
|
||||||
[production]
|
|
||||||
defaults
|
|
||||||
not IE 11
|
|
||||||
not dead
|
|
||||||
|
|
||||||
[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
|
|
289
.circleci/config.yml
Normal file
289
.circleci/config.yml
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
version: 2
|
||||||
|
|
||||||
|
aliases:
|
||||||
|
- &defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/ruby:2.7-buster-node
|
||||||
|
environment: &ruby_environment
|
||||||
|
BUNDLE_JOBS: 3
|
||||||
|
BUNDLE_RETRY: 3
|
||||||
|
BUNDLE_APP_CONFIG: ./.bundle/
|
||||||
|
BUNDLE_PATH: ./vendor/bundle/
|
||||||
|
DB_HOST: localhost
|
||||||
|
DB_USER: root
|
||||||
|
RAILS_ENV: test
|
||||||
|
ALLOW_NOPAM: true
|
||||||
|
CONTINUOUS_INTEGRATION: true
|
||||||
|
DISABLE_SIMPLECOV: true
|
||||||
|
PAM_ENABLED: true
|
||||||
|
PAM_DEFAULT_SERVICE: pam_test
|
||||||
|
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
||||||
|
working_directory: ~/projects/mastodon/
|
||||||
|
|
||||||
|
- &attach_workspace
|
||||||
|
attach_workspace:
|
||||||
|
at: ~/projects/
|
||||||
|
|
||||||
|
- &persist_to_workspace
|
||||||
|
persist_to_workspace:
|
||||||
|
root: ~/projects/
|
||||||
|
paths:
|
||||||
|
- ./mastodon/
|
||||||
|
|
||||||
|
- &restore_ruby_dependencies
|
||||||
|
restore_cache:
|
||||||
|
keys:
|
||||||
|
- v3-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
|
||||||
|
- v3-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-
|
||||||
|
- v3-ruby-dependencies-
|
||||||
|
|
||||||
|
- &install_steps
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- *attach_workspace
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- v2-node-dependencies-{{ checksum "yarn.lock" }}
|
||||||
|
- v2-node-dependencies-
|
||||||
|
- run:
|
||||||
|
name: Install yarn dependencies
|
||||||
|
command: yarn install --frozen-lockfile
|
||||||
|
- save_cache:
|
||||||
|
key: v2-node-dependencies-{{ checksum "yarn.lock" }}
|
||||||
|
paths:
|
||||||
|
- ./node_modules/
|
||||||
|
- *persist_to_workspace
|
||||||
|
|
||||||
|
- &install_system_dependencies
|
||||||
|
run:
|
||||||
|
name: Install system dependencies
|
||||||
|
command: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libicu-dev libidn11-dev libprotobuf-dev protobuf-compiler
|
||||||
|
|
||||||
|
- &install_ruby_dependencies
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *install_system_dependencies
|
||||||
|
- run:
|
||||||
|
name: Set Ruby version
|
||||||
|
command: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
|
||||||
|
- *restore_ruby_dependencies
|
||||||
|
- run:
|
||||||
|
name: Set bundler settings
|
||||||
|
command: |
|
||||||
|
bundle config --local clean 'true'
|
||||||
|
bundle config --local deployment 'true'
|
||||||
|
bundle config --local with 'pam_authentication'
|
||||||
|
bundle config --local without 'development production'
|
||||||
|
bundle config --local frozen 'true'
|
||||||
|
bundle config --local path $BUNDLE_PATH
|
||||||
|
- run:
|
||||||
|
name: Install bundler dependencies
|
||||||
|
command: bundle check || (bundle install && bundle clean)
|
||||||
|
- save_cache:
|
||||||
|
key: v3-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
|
||||||
|
paths:
|
||||||
|
- ./.bundle/
|
||||||
|
- ./vendor/bundle/
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: ~/projects/
|
||||||
|
paths:
|
||||||
|
- ./mastodon/.bundle/
|
||||||
|
- ./mastodon/vendor/bundle/
|
||||||
|
|
||||||
|
- &test_steps
|
||||||
|
parallelism: 4
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *install_system_dependencies
|
||||||
|
- run:
|
||||||
|
name: Install FFMPEG
|
||||||
|
command: sudo apt-get install -y ffmpeg
|
||||||
|
- run:
|
||||||
|
name: Load database schema
|
||||||
|
command: ./bin/rails db:create db:schema:load db:seed
|
||||||
|
- run:
|
||||||
|
name: Run rspec in parallel
|
||||||
|
command: |
|
||||||
|
bundle exec rspec --profile 10 \
|
||||||
|
--format RspecJunitFormatter \
|
||||||
|
--out test_results/rspec.xml \
|
||||||
|
--format progress \
|
||||||
|
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
|
||||||
|
- store_test_results:
|
||||||
|
path: test_results
|
||||||
|
jobs:
|
||||||
|
install:
|
||||||
|
<<: *defaults
|
||||||
|
<<: *install_steps
|
||||||
|
|
||||||
|
install-ruby2.7:
|
||||||
|
<<: *defaults
|
||||||
|
<<: *install_ruby_dependencies
|
||||||
|
|
||||||
|
install-ruby2.6:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/ruby:2.6-buster-node
|
||||||
|
environment: *ruby_environment
|
||||||
|
<<: *install_ruby_dependencies
|
||||||
|
|
||||||
|
build:
|
||||||
|
<<: *defaults
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *install_system_dependencies
|
||||||
|
- run:
|
||||||
|
name: Precompile assets
|
||||||
|
command: ./bin/rails assets:precompile
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: ~/projects/
|
||||||
|
paths:
|
||||||
|
- ./mastodon/public/assets
|
||||||
|
- ./mastodon/public/packs-test/
|
||||||
|
|
||||||
|
test-migrations:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/ruby:2.7-buster-node
|
||||||
|
environment: *ruby_environment
|
||||||
|
- image: circleci/postgres:12.2
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: root
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
- image: circleci/redis:5-alpine
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *install_system_dependencies
|
||||||
|
- run:
|
||||||
|
name: Create database
|
||||||
|
command: ./bin/rails db:create
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails db:migrate VERSION=20171010025614
|
||||||
|
name: Run migrations up to v2.0.0
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails tests:migrations:populate_v2
|
||||||
|
name: Populate database with test data
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails db:migrate
|
||||||
|
name: Run all remaining migrations
|
||||||
|
|
||||||
|
test-two-step-migrations:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/ruby:2.7-buster-node
|
||||||
|
environment: *ruby_environment
|
||||||
|
- image: circleci/postgres:12.2
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: root
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
- image: circleci/redis:5-alpine
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *install_system_dependencies
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails db:create
|
||||||
|
name: Create database
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails db:migrate VERSION=20171010025614
|
||||||
|
name: Run migrations up to v2.0.0
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails tests:migrations:populate_v2
|
||||||
|
name: Populate database with test data
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails db:migrate
|
||||||
|
name: Run all pre-deployment migrations
|
||||||
|
evironment:
|
||||||
|
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
|
||||||
|
- run:
|
||||||
|
command: ./bin/rails db:migrate
|
||||||
|
name: Run all post-deployment remaining migrations
|
||||||
|
|
||||||
|
test-ruby2.7:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/ruby:2.7-buster-node
|
||||||
|
environment: *ruby_environment
|
||||||
|
- image: circleci/postgres:12.2
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: root
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
- image: circleci/redis:5-alpine
|
||||||
|
<<: *test_steps
|
||||||
|
|
||||||
|
test-ruby2.6:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/ruby:2.6-buster-node
|
||||||
|
environment: *ruby_environment
|
||||||
|
- image: circleci/postgres:12.2
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: root
|
||||||
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
|
- image: circleci/redis:5-alpine
|
||||||
|
<<: *test_steps
|
||||||
|
|
||||||
|
test-webui:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/node:12-buster
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- run:
|
||||||
|
name: Run jest
|
||||||
|
command: yarn test:jest
|
||||||
|
|
||||||
|
check-i18n:
|
||||||
|
<<: *defaults
|
||||||
|
steps:
|
||||||
|
- *attach_workspace
|
||||||
|
- *install_system_dependencies
|
||||||
|
- run:
|
||||||
|
name: Check locale file normalization
|
||||||
|
command: bundle exec i18n-tasks check-normalized
|
||||||
|
- run:
|
||||||
|
name: Check for unused strings
|
||||||
|
command: bundle exec i18n-tasks unused -l en
|
||||||
|
- run:
|
||||||
|
name: Check for wrong string interpolations
|
||||||
|
command: bundle exec i18n-tasks check-consistent-interpolations
|
||||||
|
- run:
|
||||||
|
name: Check that all required locale files exist
|
||||||
|
command: bundle exec rake repo:check_locales_files
|
||||||
|
|
||||||
|
workflows:
|
||||||
|
version: 2
|
||||||
|
build-and-test:
|
||||||
|
jobs:
|
||||||
|
- install
|
||||||
|
- install-ruby2.7:
|
||||||
|
requires:
|
||||||
|
- install
|
||||||
|
- install-ruby2.6:
|
||||||
|
requires:
|
||||||
|
- install
|
||||||
|
- install-ruby2.7
|
||||||
|
- build:
|
||||||
|
requires:
|
||||||
|
- install-ruby2.7
|
||||||
|
- test-migrations:
|
||||||
|
requires:
|
||||||
|
- install-ruby2.7
|
||||||
|
- test-two-step-migrations:
|
||||||
|
requires:
|
||||||
|
- install-ruby2.7
|
||||||
|
- test-ruby2.7:
|
||||||
|
requires:
|
||||||
|
- install-ruby2.7
|
||||||
|
- build
|
||||||
|
- test-ruby2.6:
|
||||||
|
requires:
|
||||||
|
- install-ruby2.6
|
||||||
|
- build
|
||||||
|
- test-webui:
|
||||||
|
requires:
|
||||||
|
- install
|
||||||
|
- check-i18n:
|
||||||
|
requires:
|
||||||
|
- install-ruby2.7
|
38
.codeclimate.yml
Normal file
38
.codeclimate.yml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
version: "2"
|
||||||
|
checks:
|
||||||
|
argument-count:
|
||||||
|
enabled: false
|
||||||
|
complex-logic:
|
||||||
|
enabled: false
|
||||||
|
file-lines:
|
||||||
|
enabled: false
|
||||||
|
method-complexity:
|
||||||
|
enabled: false
|
||||||
|
method-count:
|
||||||
|
enabled: false
|
||||||
|
method-lines:
|
||||||
|
enabled: false
|
||||||
|
nested-control-flow:
|
||||||
|
enabled: false
|
||||||
|
return-statements:
|
||||||
|
enabled: false
|
||||||
|
similar-code:
|
||||||
|
enabled: false
|
||||||
|
identical-code:
|
||||||
|
enabled: false
|
||||||
|
plugins:
|
||||||
|
brakeman:
|
||||||
|
enabled: true
|
||||||
|
bundler-audit:
|
||||||
|
enabled: true
|
||||||
|
eslint:
|
||||||
|
enabled: true
|
||||||
|
channel: eslint-7
|
||||||
|
rubocop:
|
||||||
|
enabled: true
|
||||||
|
channel: rubocop-0-92
|
||||||
|
sass-lint:
|
||||||
|
enabled: true
|
||||||
|
exclude_patterns:
|
||||||
|
- spec/
|
||||||
|
- vendor/asset
|
|
@ -1,20 +0,0 @@
|
||||||
# For details, see https://github.com/devcontainers/images/tree/main/src/ruby
|
|
||||||
FROM mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye
|
|
||||||
|
|
||||||
# Install Rails
|
|
||||||
# RUN gem install rails webdrivers
|
|
||||||
|
|
||||||
ARG NODE_VERSION="16"
|
|
||||||
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"
|
|
||||||
|
|
||||||
# [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 && npm install -g yarn" 2>&1
|
|
||||||
|
|
||||||
COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
|
|
@ -1,49 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Mastodon on GitHub Codespaces",
|
|
||||||
"dockerComposeFile": "../docker-compose.yml",
|
|
||||||
"service": "app",
|
|
||||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
|
||||||
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/sshd:1": {}
|
|
||||||
},
|
|
||||||
|
|
||||||
"runServices": ["app", "db", "redis"],
|
|
||||||
|
|
||||||
"forwardPorts": [3000, 4000],
|
|
||||||
|
|
||||||
"portsAttributes": {
|
|
||||||
"3000": {
|
|
||||||
"label": "web",
|
|
||||||
"onAutoForward": "notify"
|
|
||||||
},
|
|
||||||
"4000": {
|
|
||||||
"label": "stream",
|
|
||||||
"onAutoForward": "silent"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"otherPortsAttributes": {
|
|
||||||
"onAutoForward": "silent"
|
|
||||||
},
|
|
||||||
|
|
||||||
"remoteEnv": {
|
|
||||||
"LOCAL_DOMAIN": "${localEnv:CODESPACE_NAME}-3000.app.github.dev",
|
|
||||||
"LOCAL_HTTPS": "true",
|
|
||||||
"STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev",
|
|
||||||
"DISABLE_FORGERY_REQUEST_PROTECTION": "true",
|
|
||||||
"ES_ENABLED": "",
|
|
||||||
"LIBRE_TRANSLATE_ENDPOINT": ""
|
|
||||||
},
|
|
||||||
|
|
||||||
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
|
|
||||||
"postCreateCommand": ".devcontainer/post-create.sh",
|
|
||||||
"waitFor": "postCreateCommand",
|
|
||||||
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"settings": {},
|
|
||||||
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Mastodon on local machine",
|
|
||||||
"dockerComposeFile": "docker-compose.yml",
|
|
||||||
"service": "app",
|
|
||||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
|
||||||
|
|
||||||
"features": {
|
|
||||||
"ghcr.io/devcontainers/features/sshd:1": {}
|
|
||||||
},
|
|
||||||
|
|
||||||
"forwardPorts": [3000, 4000],
|
|
||||||
|
|
||||||
"portsAttributes": {
|
|
||||||
"3000": {
|
|
||||||
"label": "web",
|
|
||||||
"onAutoForward": "notify",
|
|
||||||
"requireLocalPort": true
|
|
||||||
},
|
|
||||||
"4000": {
|
|
||||||
"label": "stream",
|
|
||||||
"onAutoForward": "silent",
|
|
||||||
"requireLocalPort": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
"otherPortsAttributes": {
|
|
||||||
"onAutoForward": "silent"
|
|
||||||
},
|
|
||||||
|
|
||||||
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
|
|
||||||
"postCreateCommand": ".devcontainer/post-create.sh",
|
|
||||||
"waitFor": "postCreateCommand",
|
|
||||||
|
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"settings": {},
|
|
||||||
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
volumes:
|
|
||||||
- ../..:/workspaces:cached
|
|
||||||
environment:
|
|
||||||
RAILS_ENV: development
|
|
||||||
NODE_ENV: development
|
|
||||||
BIND: 0.0.0.0
|
|
||||||
REDIS_HOST: redis
|
|
||||||
REDIS_PORT: '6379'
|
|
||||||
DB_HOST: db
|
|
||||||
DB_USER: postgres
|
|
||||||
DB_PASS: postgres
|
|
||||||
DB_PORT: '5432'
|
|
||||||
ES_ENABLED: 'true'
|
|
||||||
ES_HOST: es
|
|
||||||
ES_PORT: '9200'
|
|
||||||
LIBRE_TRANSLATE_ENDPOINT: http://libretranslate:5000
|
|
||||||
# Overrides default command so things don't shut down after the process ends.
|
|
||||||
command: sleep infinity
|
|
||||||
ports:
|
|
||||||
- '127.0.0.1:3000:3000'
|
|
||||||
- '127.0.0.1:3035:3035'
|
|
||||||
- '127.0.0.1:4000:4000'
|
|
||||||
networks:
|
|
||||||
- external_network
|
|
||||||
- internal_network
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: postgres:14-alpine
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- postgres-data:/var/lib/postgresql/data
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
POSTGRES_DB: postgres
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- redis-data:/data
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
|
|
||||||
es:
|
|
||||||
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
ES_JAVA_OPTS: -Xms512m -Xmx512m
|
|
||||||
cluster.name: es-mastodon
|
|
||||||
discovery.type: single-node
|
|
||||||
bootstrap.memory_lock: 'true'
|
|
||||||
volumes:
|
|
||||||
- es-data:/usr/share/elasticsearch/data
|
|
||||||
networks:
|
|
||||||
- internal_network
|
|
||||||
ulimits:
|
|
||||||
memlock:
|
|
||||||
soft: -1
|
|
||||||
hard: -1
|
|
||||||
|
|
||||||
libretranslate:
|
|
||||||
image: libretranslate/libretranslate:v1.3.11
|
|
||||||
restart: unless-stopped
|
|
||||||
volumes:
|
|
||||||
- lt-data:/home/libretranslate/.local
|
|
||||||
networks:
|
|
||||||
- external_network
|
|
||||||
- internal_network
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres-data:
|
|
||||||
redis-data:
|
|
||||||
es-data:
|
|
||||||
lt-data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
external_network:
|
|
||||||
internal_network:
|
|
||||||
internal: true
|
|
|
@ -1,26 +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
|
|
||||||
yarn --frozen-lockfile
|
|
||||||
|
|
||||||
# [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 NODE_ENV=tests ./bin/rails assets:precompile
|
|
|
@ -1,8 +0,0 @@
|
||||||
👋 Welcome to "Mastodon" in GitHub Codespaces!
|
|
||||||
|
|
||||||
🛠️ 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.
|
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
.bundle
|
.bundle
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
.git
|
|
||||||
.gitattributes
|
|
||||||
.gitignore
|
|
||||||
.github
|
|
||||||
public/system
|
public/system
|
||||||
public/assets
|
public/assets
|
||||||
public/packs
|
public/packs
|
||||||
|
@ -15,7 +11,5 @@ vendor/bundle
|
||||||
*.swp
|
*.swp
|
||||||
*~
|
*~
|
||||||
postgres
|
postgres
|
||||||
postgres14
|
|
||||||
redis
|
redis
|
||||||
elasticsearch
|
elasticsearch
|
||||||
chart
|
|
||||||
|
|
|
@ -10,4 +10,3 @@ insert_final_newline = true
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
trim_trailing_whitespace = true
|
|
||||||
|
|
257
.env.nanobox
Normal file
257
.env.nanobox
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
# Service dependencies
|
||||||
|
# You may set REDIS_URL instead for more advanced options
|
||||||
|
REDIS_HOST=$DATA_REDIS_HOST
|
||||||
|
REDIS_PORT=6379
|
||||||
|
# REDIS_DB=0
|
||||||
|
|
||||||
|
# You may set DATABASE_URL instead for more advanced options
|
||||||
|
DB_HOST=$DATA_DB_HOST
|
||||||
|
DB_USER=$DATA_DB_USER
|
||||||
|
DB_NAME=gonano
|
||||||
|
DB_PASS=$DATA_DB_PASS
|
||||||
|
DB_PORT=5432
|
||||||
|
|
||||||
|
# DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano
|
||||||
|
|
||||||
|
# Optional ElasticSearch configuration
|
||||||
|
ES_ENABLED=true
|
||||||
|
ES_HOST=$DATA_ELASTIC_HOST
|
||||||
|
ES_PORT=9200
|
||||||
|
|
||||||
|
BIND=0.0.0.0
|
||||||
|
|
||||||
|
# Federation
|
||||||
|
# Note: Changing LOCAL_DOMAIN at a later time will cause unwanted side effects, including breaking all existing federation.
|
||||||
|
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
||||||
|
LOCAL_DOMAIN=${APP_NAME}.nanoapp.io
|
||||||
|
|
||||||
|
# Changing LOCAL_HTTPS in production is no longer supported. (Mastodon will always serve https:// links)
|
||||||
|
|
||||||
|
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
||||||
|
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
||||||
|
# DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
|
||||||
|
# WEB_DOMAIN=mastodon.example.com
|
||||||
|
|
||||||
|
# Use this if you want to have several aliases handler@example1.com
|
||||||
|
# handler@example2.com etc. for the same user. LOCAL_DOMAIN should not
|
||||||
|
# be added. Comma separated values
|
||||||
|
# ALTERNATE_DOMAINS=example1.com,example2.com
|
||||||
|
|
||||||
|
# Application secrets
|
||||||
|
# Generate each with the `rake secret` task (`nanobox run bundle exec rake secret`)
|
||||||
|
SECRET_KEY_BASE=$SECRET_KEY_BASE
|
||||||
|
OTP_SECRET=$OTP_SECRET
|
||||||
|
|
||||||
|
# VAPID keys (used for push notifications)
|
||||||
|
# You can generate the keys using the following command (first is the private key, second is the public one)
|
||||||
|
# You should only generate this once per instance. If you later decide to change it, all push subscription will
|
||||||
|
# be invalidated, requiring the users to access the website again to resubscribe.
|
||||||
|
#
|
||||||
|
# Generate with `rake mastodon:webpush:generate_vapid_key` task (`nanobox run bundle exec rake mastodon:webpush:generate_vapid_key`)
|
||||||
|
#
|
||||||
|
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
||||||
|
VAPID_PRIVATE_KEY=$VAPID_PRIVATE_KEY
|
||||||
|
VAPID_PUBLIC_KEY=$VAPID_PUBLIC_KEY
|
||||||
|
|
||||||
|
# Registrations
|
||||||
|
# Single user mode will disable registrations and redirect frontpage to the first profile
|
||||||
|
# SINGLE_USER_MODE=true
|
||||||
|
# Prevent registrations with following e-mail domains
|
||||||
|
# EMAIL_DOMAIN_BLACKLIST=example1.com|example2.de|etc
|
||||||
|
# Only allow registrations with the following e-mail domains
|
||||||
|
# EMAIL_DOMAIN_WHITELIST=example1.com|example2.de|etc
|
||||||
|
|
||||||
|
# Optionally change default language
|
||||||
|
# DEFAULT_LOCALE=de
|
||||||
|
|
||||||
|
# E-mail configuration
|
||||||
|
# Note: Mailgun and SparkPost (https://sparkpo.st/smtp) each have good free tiers
|
||||||
|
# If you want to use an SMTP server without authentication (e.g local Postfix relay)
|
||||||
|
# then set SMTP_AUTH_METHOD and SMTP_OPENSSL_VERIFY_MODE to 'none' and
|
||||||
|
# *comment* SMTP_LOGIN and SMTP_PASSWORD (leaving them blank is not enough).
|
||||||
|
SMTP_SERVER=$SMTP_SERVER
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_LOGIN=$SMTP_LOGIN
|
||||||
|
SMTP_PASSWORD=$SMTP_PASSWORD
|
||||||
|
SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
||||||
|
#SMTP_REPLY_TO=
|
||||||
|
#SMTP_DOMAIN= # defaults to LOCAL_DOMAIN
|
||||||
|
#SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail
|
||||||
|
#SMTP_AUTH_METHOD=plain
|
||||||
|
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||||
|
#SMTP_OPENSSL_VERIFY_MODE=peer
|
||||||
|
#SMTP_ENABLE_STARTTLS_AUTO=true
|
||||||
|
#SMTP_TLS=true
|
||||||
|
|
||||||
|
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
|
||||||
|
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
||||||
|
# PAPERCLIP_ROOT_URL=/system
|
||||||
|
|
||||||
|
# Optional asset host for multi-server setups
|
||||||
|
# The asset host must allow cross origin request from WEB_DOMAIN or LOCAL_DOMAIN
|
||||||
|
# if WEB_DOMAIN is not set. For example, the server may have the
|
||||||
|
# following header field:
|
||||||
|
# Access-Control-Allow-Origin: https://example.com/
|
||||||
|
# CDN_HOST=https://assets.example.com
|
||||||
|
|
||||||
|
# S3 (optional)
|
||||||
|
# The attachment host must allow cross origin request from WEB_DOMAIN or
|
||||||
|
# LOCAL_DOMAIN if WEB_DOMAIN is not set. For example, the server may have the
|
||||||
|
# following header field:
|
||||||
|
# Access-Control-Allow-Origin: https://192.168.1.123:9000/
|
||||||
|
# S3_ENABLED=true
|
||||||
|
# S3_BUCKET=
|
||||||
|
# AWS_ACCESS_KEY_ID=
|
||||||
|
# AWS_SECRET_ACCESS_KEY=
|
||||||
|
# S3_REGION=
|
||||||
|
# S3_PROTOCOL=http
|
||||||
|
# S3_HOSTNAME=192.168.1.123:9000
|
||||||
|
|
||||||
|
# S3 (Minio Config (optional) Please check Minio instance for details)
|
||||||
|
# The attachment host must allow cross origin request - see the description
|
||||||
|
# above.
|
||||||
|
# S3_ENABLED=true
|
||||||
|
# S3_BUCKET=
|
||||||
|
# AWS_ACCESS_KEY_ID=
|
||||||
|
# AWS_SECRET_ACCESS_KEY=
|
||||||
|
# S3_REGION=
|
||||||
|
# S3_PROTOCOL=https
|
||||||
|
# S3_HOSTNAME=
|
||||||
|
# S3_ENDPOINT=
|
||||||
|
# S3_SIGNATURE_VERSION=
|
||||||
|
|
||||||
|
# Google Cloud Storage (optional)
|
||||||
|
# Use S3 compatible API. Since GCS does not support Multipart Upload,
|
||||||
|
# increase the value of S3_MULTIPART_THRESHOLD to disable Multipart Upload.
|
||||||
|
# The attachment host must allow cross origin request - see the description
|
||||||
|
# above.
|
||||||
|
# S3_ENABLED=true
|
||||||
|
# AWS_ACCESS_KEY_ID=
|
||||||
|
# AWS_SECRET_ACCESS_KEY=
|
||||||
|
# S3_REGION=
|
||||||
|
# S3_PROTOCOL=https
|
||||||
|
# S3_HOSTNAME=storage.googleapis.com
|
||||||
|
# S3_ENDPOINT=https://storage.googleapis.com
|
||||||
|
# S3_MULTIPART_THRESHOLD=52428801 # 50.megabytes
|
||||||
|
|
||||||
|
# Swift (optional)
|
||||||
|
# The attachment host must allow cross origin request - see the description
|
||||||
|
# above.
|
||||||
|
# SWIFT_ENABLED=true
|
||||||
|
# SWIFT_USERNAME=
|
||||||
|
# For Keystone V3, the value for SWIFT_TENANT should be the project name
|
||||||
|
# SWIFT_TENANT=
|
||||||
|
# SWIFT_PASSWORD=
|
||||||
|
# Some OpenStack V3 providers require PROJECT_ID (optional)
|
||||||
|
# SWIFT_PROJECT_ID=
|
||||||
|
# Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid
|
||||||
|
# issues with token rate-limiting during high load.
|
||||||
|
# SWIFT_AUTH_URL=
|
||||||
|
# SWIFT_CONTAINER=
|
||||||
|
# SWIFT_OBJECT_URL=
|
||||||
|
# SWIFT_REGION=
|
||||||
|
# Defaults to 'default'
|
||||||
|
# SWIFT_DOMAIN_NAME=
|
||||||
|
# Defaults to 60 seconds. Set to 0 to disable
|
||||||
|
# SWIFT_CACHE_TTL=
|
||||||
|
|
||||||
|
# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
|
||||||
|
# S3_ALIAS_HOST=
|
||||||
|
|
||||||
|
# Streaming API integration
|
||||||
|
# STREAMING_API_BASE_URL=
|
||||||
|
|
||||||
|
# Advanced settings
|
||||||
|
# If you need to use pgBouncer, you need to disable prepared statements:
|
||||||
|
# PREPARED_STATEMENTS=false
|
||||||
|
|
||||||
|
# Cluster number setting for streaming API server.
|
||||||
|
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
|
||||||
|
# STREAMING_CLUSTER_NUM=1
|
||||||
|
|
||||||
|
# Docker mastodon user
|
||||||
|
# If you use Docker, you may want to assign UID/GID manually.
|
||||||
|
# UID=1000
|
||||||
|
# GID=1000
|
||||||
|
|
||||||
|
# LDAP authentication (optional)
|
||||||
|
# LDAP_ENABLED=true
|
||||||
|
# LDAP_HOST=localhost
|
||||||
|
# LDAP_PORT=389
|
||||||
|
# LDAP_METHOD=simple_tls
|
||||||
|
# LDAP_BASE=
|
||||||
|
# LDAP_BIND_DN=
|
||||||
|
# LDAP_PASSWORD=
|
||||||
|
# LDAP_UID=cn
|
||||||
|
# LDAP_MAIL=mail
|
||||||
|
# LDAP_SEARCH_FILTER=(|(%{uid}=%{email})(%{mail}=%{email}))
|
||||||
|
# LDAP_UID_CONVERSION_ENABLED=true
|
||||||
|
# LDAP_UID_CONVERSION_SEARCH=., -
|
||||||
|
# LDAP_UID_CONVERSION_REPLACE=_
|
||||||
|
|
||||||
|
# PAM authentication (optional)
|
||||||
|
# PAM authentication uses for the email generation the "email" pam variable
|
||||||
|
# and optional as fallback PAM_DEFAULT_SUFFIX
|
||||||
|
# The pam environment variable "email" is provided by:
|
||||||
|
# https://github.com/devkral/pam_email_extractor
|
||||||
|
# PAM_ENABLED=true
|
||||||
|
# Fallback email domain for email address generation (LOCAL_DOMAIN by default)
|
||||||
|
# PAM_EMAIL_DOMAIN=example.com
|
||||||
|
# Name of the pam service (pam "auth" section is evaluated)
|
||||||
|
# PAM_DEFAULT_SERVICE=rpam
|
||||||
|
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
|
||||||
|
# PAM_CONTROLLED_SERVICE=rpam
|
||||||
|
|
||||||
|
# Global OAuth settings (optional) :
|
||||||
|
# If you have only one strategy, you may want to enable this
|
||||||
|
# OAUTH_REDIRECT_AT_SIGN_IN=true
|
||||||
|
|
||||||
|
# Optional CAS authentication (cf. omniauth-cas) :
|
||||||
|
# CAS_ENABLED=true
|
||||||
|
# CAS_URL=https://sso.myserver.com/
|
||||||
|
# CAS_HOST=sso.myserver.com/
|
||||||
|
# CAS_PORT=443
|
||||||
|
# CAS_SSL=true
|
||||||
|
# CAS_VALIDATE_URL=
|
||||||
|
# CAS_CALLBACK_URL=
|
||||||
|
# CAS_LOGOUT_URL=
|
||||||
|
# CAS_LOGIN_URL=
|
||||||
|
# CAS_UID_FIELD='user'
|
||||||
|
# CAS_CA_PATH=
|
||||||
|
# CAS_DISABLE_SSL_VERIFICATION=false
|
||||||
|
# CAS_UID_KEY='user'
|
||||||
|
# CAS_NAME_KEY='name'
|
||||||
|
# CAS_EMAIL_KEY='email'
|
||||||
|
# CAS_NICKNAME_KEY='nickname'
|
||||||
|
# CAS_FIRST_NAME_KEY='firstname'
|
||||||
|
# CAS_LAST_NAME_KEY='lastname'
|
||||||
|
# CAS_LOCATION_KEY='location'
|
||||||
|
# CAS_IMAGE_KEY='image'
|
||||||
|
# CAS_PHONE_KEY='phone'
|
||||||
|
|
||||||
|
# Optional SAML authentication (cf. omniauth-saml)
|
||||||
|
# SAML_ENABLED=true
|
||||||
|
# SAML_ACS_URL=http://localhost:3000/auth/auth/saml/callback
|
||||||
|
# SAML_ISSUER=https://example.com
|
||||||
|
# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO
|
||||||
|
# SAML_IDP_CERT=
|
||||||
|
# SAML_IDP_CERT_FINGERPRINT=
|
||||||
|
# SAML_NAME_IDENTIFIER_FORMAT=
|
||||||
|
# SAML_CERT=
|
||||||
|
# SAML_PRIVATE_KEY=
|
||||||
|
# SAML_SECURITY_WANT_ASSERTION_SIGNED=true
|
||||||
|
# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true
|
||||||
|
# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1"
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241"
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42"
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4"
|
||||||
|
# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1"
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED=
|
||||||
|
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL=
|
||||||
|
|
||||||
|
# Use HTTP proxy for outgoing request (optional)
|
||||||
|
# http_proxy=http://gateway.local:8118
|
||||||
|
# Access control for hidden service.
|
||||||
|
# ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
|
|
@ -29,14 +29,11 @@ DB_NAME=mastodon_production
|
||||||
DB_PASS=
|
DB_PASS=
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
|
|
||||||
# Elasticsearch (optional)
|
# ElasticSearch (optional)
|
||||||
# ------------------------
|
# ------------------------
|
||||||
ES_ENABLED=true
|
ES_ENABLED=true
|
||||||
ES_HOST=localhost
|
ES_HOST=localhost
|
||||||
ES_PORT=9200
|
ES_PORT=9200
|
||||||
# Authentication for ES (optional)
|
|
||||||
ES_USER=elastic
|
|
||||||
ES_PASS=password
|
|
||||||
|
|
||||||
# Secrets
|
# Secrets
|
||||||
# -------
|
# -------
|
||||||
|
@ -54,11 +51,11 @@ VAPID_PUBLIC_KEY=
|
||||||
|
|
||||||
# Sending mail
|
# Sending mail
|
||||||
# ------------
|
# ------------
|
||||||
SMTP_SERVER=
|
SMTP_SERVER=smtp.mailgun.org
|
||||||
SMTP_PORT=587
|
SMTP_PORT=587
|
||||||
SMTP_LOGIN=
|
SMTP_LOGIN=
|
||||||
SMTP_PASSWORD=
|
SMTP_PASSWORD=
|
||||||
SMTP_FROM_ADDRESS=notifications@example.com
|
SMTP_FROM_ADDRESS=notificatons@example.com
|
||||||
|
|
||||||
# File storage (optional)
|
# File storage (optional)
|
||||||
# -----------------------
|
# -----------------------
|
||||||
|
@ -67,11 +64,3 @@ S3_BUCKET=files.example.com
|
||||||
AWS_ACCESS_KEY_ID=
|
AWS_ACCESS_KEY_ID=
|
||||||
AWS_SECRET_ACCESS_KEY=
|
AWS_SECRET_ACCESS_KEY=
|
||||||
S3_ALIAS_HOST=files.example.com
|
S3_ALIAS_HOST=files.example.com
|
||||||
|
|
||||||
# IP and session retention
|
|
||||||
# -----------------------
|
|
||||||
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
|
|
||||||
# to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).
|
|
||||||
# -----------------------
|
|
||||||
IP_RETENTION_PERIOD=31556952
|
|
||||||
SESSION_RETENTION_PERIOD=31556952
|
|
||||||
|
|
|
@ -2,7 +2,3 @@ VAGRANT=true
|
||||||
LOCAL_DOMAIN=mastodon.local
|
LOCAL_DOMAIN=mastodon.local
|
||||||
BIND=0.0.0.0
|
BIND=0.0.0.0
|
||||||
DB_HOST=/var/run/postgresql/
|
DB_HOST=/var/run/postgresql/
|
||||||
|
|
||||||
ES_ENABLED=true
|
|
||||||
ES_HOST=localhost
|
|
||||||
ES_PORT=9200
|
|
357
.eslintrc.js
357
.eslintrc.js
|
@ -1,71 +1,71 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:react/recommended',
|
|
||||||
'plugin:react-hooks/recommended',
|
|
||||||
'plugin:jsx-a11y/recommended',
|
|
||||||
'plugin:import/recommended',
|
|
||||||
'plugin:promise/recommended',
|
|
||||||
'plugin:jsdoc/recommended',
|
|
||||||
'plugin:prettier/recommended',
|
|
||||||
],
|
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
node: true,
|
node: true,
|
||||||
es6: true,
|
es6: true,
|
||||||
|
jest: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
globals: {
|
globals: {
|
||||||
ATTACHMENT_HOST: false,
|
ATTACHMENT_HOST: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser',
|
parser: 'babel-eslint',
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
'react',
|
'react',
|
||||||
'jsx-a11y',
|
'jsx-a11y',
|
||||||
'import',
|
'import',
|
||||||
'promise',
|
'promise',
|
||||||
'@typescript-eslint',
|
|
||||||
'formatjs',
|
|
||||||
],
|
],
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
sourceType: 'module',
|
sourceType: 'module',
|
||||||
ecmaFeatures: {
|
ecmaFeatures: {
|
||||||
|
experimentalObjectRestSpread: true,
|
||||||
jsx: true,
|
jsx: true,
|
||||||
},
|
},
|
||||||
ecmaVersion: 2021,
|
ecmaVersion: 2018,
|
||||||
requireConfigFile: false,
|
|
||||||
babelOptions: {
|
|
||||||
configFile: false,
|
|
||||||
presets: ['@babel/react', '@babel/env'],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
settings: {
|
settings: {
|
||||||
react: {
|
react: {
|
||||||
version: 'detect',
|
version: 'detect',
|
||||||
},
|
},
|
||||||
|
'import/extensions': [
|
||||||
|
'.js',
|
||||||
|
],
|
||||||
'import/ignore': [
|
'import/ignore': [
|
||||||
'node_modules',
|
'node_modules',
|
||||||
'\\.(css|scss|json)$',
|
'\\.(css|scss|json)$',
|
||||||
],
|
],
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
typescript: {},
|
node: {
|
||||||
|
paths: ['app/javascript'],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
|
'brace-style': 'warn',
|
||||||
|
'comma-dangle': ['error', 'always-multiline'],
|
||||||
|
'comma-spacing': [
|
||||||
|
'warn',
|
||||||
|
{
|
||||||
|
before: false,
|
||||||
|
after: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'comma-style': ['warn', 'last'],
|
||||||
'consistent-return': 'error',
|
'consistent-return': 'error',
|
||||||
'dot-notation': 'error',
|
'dot-notation': 'error',
|
||||||
eqeqeq: ['error', 'always', { 'null': 'ignore' }],
|
eqeqeq: 'error',
|
||||||
|
indent: ['warn', 2],
|
||||||
'jsx-quotes': ['error', 'prefer-single'],
|
'jsx-quotes': ['error', 'prefer-single'],
|
||||||
'no-case-declarations': 'off',
|
|
||||||
'no-catch-shadow': 'error',
|
'no-catch-shadow': 'error',
|
||||||
|
'no-cond-assign': 'error',
|
||||||
'no-console': [
|
'no-console': [
|
||||||
'warn',
|
'warn',
|
||||||
{
|
{
|
||||||
|
@ -75,75 +75,86 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-empty': 'off',
|
'no-fallthrough': 'error',
|
||||||
'no-restricted-properties': [
|
'no-irregular-whitespace': 'error',
|
||||||
'error',
|
'no-mixed-spaces-and-tabs': 'warn',
|
||||||
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
'no-nested-ternary': 'warn',
|
||||||
{ property: 'substr', message: 'Use .slice instead of .substr.' },
|
'no-trailing-spaces': 'warn',
|
||||||
],
|
'no-undef': 'error',
|
||||||
'no-restricted-syntax': [
|
'no-unreachable': 'error',
|
||||||
'error',
|
|
||||||
{
|
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
|
||||||
selector: 'Literal[value=/•/], JSXText[value=/•/]',
|
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
|
||||||
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'no-self-assign': 'off',
|
|
||||||
'no-unused-expressions': 'error',
|
'no-unused-expressions': 'error',
|
||||||
'no-unused-vars': 'off',
|
'no-unused-vars': [
|
||||||
'@typescript-eslint/no-unused-vars': [
|
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
vars: 'all',
|
vars: 'all',
|
||||||
args: 'after-used',
|
args: 'after-used',
|
||||||
destructuredArrayIgnorePattern: '^_',
|
|
||||||
ignoreRestSiblings: true,
|
ignoreRestSiblings: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'object-curly-spacing': ['error', 'always'],
|
||||||
|
'padded-blocks': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
classes: 'always',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
quotes: ['error', 'single'],
|
||||||
|
semi: 'error',
|
||||||
|
strict: 'off',
|
||||||
'valid-typeof': 'error',
|
'valid-typeof': 'error',
|
||||||
|
|
||||||
'react/jsx-filename-extension': ['error', { extensions: ['.jsx', 'tsx'] }],
|
|
||||||
'react/jsx-boolean-value': 'error',
|
'react/jsx-boolean-value': 'error',
|
||||||
'react/display-name': 'off',
|
'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
|
||||||
'react/jsx-fragments': ['error', 'syntax'],
|
'react/jsx-curly-spacing': 'error',
|
||||||
'react/jsx-equals-spacing': 'error',
|
'react/jsx-equals-spacing': 'error',
|
||||||
|
'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
|
||||||
|
'react/jsx-indent': ['error', 2],
|
||||||
'react/jsx-no-bind': 'error',
|
'react/jsx-no-bind': 'error',
|
||||||
'react/jsx-no-useless-fragment': 'error',
|
'react/jsx-no-duplicate-props': 'error',
|
||||||
'react/jsx-no-target-blank': 'off',
|
'react/jsx-no-undef': 'error',
|
||||||
'react/jsx-tag-spacing': 'error',
|
'react/jsx-tag-spacing': 'error',
|
||||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
'react/jsx-uses-react': 'error',
|
||||||
|
'react/jsx-uses-vars': 'error',
|
||||||
'react/jsx-wrap-multilines': 'error',
|
'react/jsx-wrap-multilines': 'error',
|
||||||
'react/no-deprecated': 'off',
|
'react/no-multi-comp': 'off',
|
||||||
'react/no-unknown-property': 'off',
|
'react/no-string-refs': 'error',
|
||||||
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
'react/prop-types': 'error',
|
||||||
'react/self-closing-comp': 'error',
|
'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',
|
'jsx-a11y/accessible-emoji': 'warn',
|
||||||
'jsx-a11y/click-events-have-key-events': 'off',
|
'jsx-a11y/alt-text': 'warn',
|
||||||
'jsx-a11y/label-has-associated-control': 'off',
|
'jsx-a11y/anchor-has-content': 'warn',
|
||||||
'jsx-a11y/media-has-caption': 'off',
|
'jsx-a11y/anchor-is-valid': [
|
||||||
'jsx-a11y/no-autofocus': 'off',
|
'warn',
|
||||||
// recommended rule is:
|
{
|
||||||
// 'jsx-a11y/no-interactive-element-to-noninteractive-role': [
|
components: [
|
||||||
// 'error',
|
'Link',
|
||||||
// {
|
'NavLink',
|
||||||
// tr: ['none', 'presentation'],
|
],
|
||||||
// canvas: ['img'],
|
specialLink: [
|
||||||
// },
|
'to',
|
||||||
// ],
|
],
|
||||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
aspect: [
|
||||||
// recommended rule is:
|
'noHref',
|
||||||
// 'jsx-a11y/no-noninteractive-element-interactions': [
|
'invalidHref',
|
||||||
// 'error',
|
'preferButton',
|
||||||
// {
|
],
|
||||||
// body: ['onError', 'onLoad'],
|
},
|
||||||
// iframe: ['onError', 'onLoad'],
|
],
|
||||||
// img: ['onError', 'onLoad'],
|
'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
|
||||||
// },
|
'jsx-a11y/aria-props': 'warn',
|
||||||
// ],
|
'jsx-a11y/aria-proptypes': 'warn',
|
||||||
|
'jsx-a11y/aria-role': 'warn',
|
||||||
|
'jsx-a11y/aria-unsupported-elements': 'warn',
|
||||||
|
'jsx-a11y/heading-has-content': 'warn',
|
||||||
|
'jsx-a11y/html-has-lang': 'warn',
|
||||||
|
'jsx-a11y/iframe-has-title': 'warn',
|
||||||
|
'jsx-a11y/img-redundant-alt': 'warn',
|
||||||
|
'jsx-a11y/interactive-supports-focus': 'warn',
|
||||||
|
'jsx-a11y/label-has-for': 'off',
|
||||||
|
'jsx-a11y/mouse-events-have-key-events': 'warn',
|
||||||
|
'jsx-a11y/no-access-key': 'warn',
|
||||||
|
'jsx-a11y/no-distracting-elements': 'warn',
|
||||||
'jsx-a11y/no-noninteractive-element-interactions': [
|
'jsx-a11y/no-noninteractive-element-interactions': [
|
||||||
'warn',
|
'warn',
|
||||||
{
|
{
|
||||||
|
@ -152,18 +163,8 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// recommended rule is:
|
|
||||||
// 'jsx-a11y/no-noninteractive-tabindex': [
|
|
||||||
// 'error',
|
|
||||||
// {
|
|
||||||
// tags: [],
|
|
||||||
// roles: ['tabpanel'],
|
|
||||||
// allowExpressionValues: true,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
|
||||||
'jsx-a11y/no-onchange': 'warn',
|
'jsx-a11y/no-onchange': 'warn',
|
||||||
// recommended is full 'error'
|
'jsx-a11y/no-redundant-roles': 'warn',
|
||||||
'jsx-a11y/no-static-element-interactions': [
|
'jsx-a11y/no-static-element-interactions': [
|
||||||
'warn',
|
'warn',
|
||||||
{
|
{
|
||||||
|
@ -172,213 +173,37 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'jsx-a11y/role-has-required-aria-props': 'warn',
|
||||||
|
'jsx-a11y/role-supports-aria-props': 'off',
|
||||||
|
'jsx-a11y/scope': 'warn',
|
||||||
|
'jsx-a11y/tabindex-no-positive': 'warn',
|
||||||
|
|
||||||
// See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js
|
|
||||||
'import/extensions': [
|
'import/extensions': [
|
||||||
'error',
|
'error',
|
||||||
'always',
|
'always',
|
||||||
{
|
{
|
||||||
js: 'never',
|
js: 'never',
|
||||||
jsx: 'never',
|
|
||||||
mjs: 'never',
|
|
||||||
ts: 'never',
|
|
||||||
tsx: 'never',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'import/first': 'error',
|
|
||||||
'import/newline-after-import': 'error',
|
'import/newline-after-import': 'error',
|
||||||
'import/no-anonymous-default-export': 'error',
|
|
||||||
'import/no-extraneous-dependencies': [
|
'import/no-extraneous-dependencies': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
devDependencies: [
|
devDependencies: [
|
||||||
'config/webpack/**',
|
'config/webpack/**',
|
||||||
'app/javascript/mastodon/performance.js',
|
|
||||||
'app/javascript/mastodon/test_setup.js',
|
'app/javascript/mastodon/test_setup.js',
|
||||||
'app/javascript/**/__tests__/**',
|
'app/javascript/**/__tests__/**',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'import/no-amd': 'error',
|
'import/no-unresolved': 'error',
|
||||||
'import/no-commonjs': 'error',
|
|
||||||
'import/no-import-module-exports': 'error',
|
|
||||||
'import/no-relative-packages': 'error',
|
|
||||||
'import/no-self-import': 'error',
|
|
||||||
'import/no-useless-path-segments': 'error',
|
|
||||||
'import/no-webpack-loader-syntax': 'error',
|
'import/no-webpack-loader-syntax': 'error',
|
||||||
|
|
||||||
'import/order': [
|
|
||||||
'error',
|
|
||||||
{
|
|
||||||
alphabetize: { order: 'asc' },
|
|
||||||
'newlines-between': 'always',
|
|
||||||
groups: [
|
|
||||||
'builtin',
|
|
||||||
'external',
|
|
||||||
'internal',
|
|
||||||
'parent',
|
|
||||||
['index', 'sibling'],
|
|
||||||
'object',
|
|
||||||
],
|
|
||||||
pathGroups: [
|
|
||||||
// React core packages
|
|
||||||
{
|
|
||||||
pattern: '{react,react-dom,react-dom/client,prop-types}',
|
|
||||||
group: 'builtin',
|
|
||||||
position: 'after',
|
|
||||||
},
|
|
||||||
// I18n
|
|
||||||
{
|
|
||||||
pattern: '{react-intl,intl-messageformat}',
|
|
||||||
group: 'builtin',
|
|
||||||
position: 'after',
|
|
||||||
},
|
|
||||||
// Common React utilities
|
|
||||||
{
|
|
||||||
pattern: '{classnames,react-helmet,react-router-dom}',
|
|
||||||
group: 'external',
|
|
||||||
position: 'before',
|
|
||||||
},
|
|
||||||
// Immutable / Redux / data store
|
|
||||||
{
|
|
||||||
pattern: '{immutable,react-redux,react-immutable-proptypes,react-immutable-pure-component,reselect}',
|
|
||||||
group: 'external',
|
|
||||||
position: 'before',
|
|
||||||
},
|
|
||||||
// Internal packages
|
|
||||||
{
|
|
||||||
pattern: '{mastodon/**}',
|
|
||||||
group: 'internal',
|
|
||||||
position: 'after',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
pathGroupsExcludedImportTypes: [],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
'promise/always-return': 'off',
|
|
||||||
'promise/catch-or-return': [
|
'promise/catch-or-return': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
allowFinally: true,
|
allowFinally: true,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'promise/no-callback-in-promise': 'off',
|
|
||||||
'promise/no-nesting': 'off',
|
|
||||||
'promise/no-promise-in-callback': 'off',
|
|
||||||
|
|
||||||
'formatjs/blocklist-elements': 'error',
|
|
||||||
'formatjs/enforce-default-message': ['error', 'literal'],
|
|
||||||
'formatjs/enforce-description': 'off', // description values not currently used
|
|
||||||
'formatjs/enforce-id': 'off', // Explicit IDs are used in the project
|
|
||||||
'formatjs/enforce-placeholders': 'off', // Issues in short_number.jsx
|
|
||||||
'formatjs/enforce-plural-rules': 'error',
|
|
||||||
'formatjs/no-camel-case': 'off', // disabledAccount is only non-conforming
|
|
||||||
'formatjs/no-complex-selectors': 'error',
|
|
||||||
'formatjs/no-emoji': 'error',
|
|
||||||
'formatjs/no-id': 'off', // IDs are used for translation keys
|
|
||||||
'formatjs/no-invalid-icu': 'error',
|
|
||||||
'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings
|
|
||||||
'formatjs/no-multiple-plurals': 'off', // Only used by hashtag.jsx
|
|
||||||
'formatjs/no-multiple-whitespaces': 'error',
|
|
||||||
'formatjs/no-offset': 'error',
|
|
||||||
'formatjs/no-useless-message': 'error',
|
|
||||||
'formatjs/prefer-formatted-message': 'error',
|
|
||||||
'formatjs/prefer-pound-in-plural': 'error',
|
|
||||||
|
|
||||||
'jsdoc/check-types': 'off',
|
|
||||||
'jsdoc/no-undefined-types': 'off',
|
|
||||||
'jsdoc/require-jsdoc': 'off',
|
|
||||||
'jsdoc/require-param-description': 'off',
|
|
||||||
'jsdoc/require-property-description': 'off',
|
|
||||||
'jsdoc/require-returns-description': 'off',
|
|
||||||
'jsdoc/require-returns': 'off',
|
|
||||||
},
|
},
|
||||||
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'*.config.js',
|
|
||||||
'.*rc.js',
|
|
||||||
'ide-helper.js',
|
|
||||||
'config/webpack/**/*',
|
|
||||||
'config/formatjs-formatter.js',
|
|
||||||
],
|
|
||||||
|
|
||||||
env: {
|
|
||||||
commonjs: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'script',
|
|
||||||
},
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
'import/no-commonjs': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'**/*.ts',
|
|
||||||
'**/*.tsx',
|
|
||||||
],
|
|
||||||
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/strict-type-checked',
|
|
||||||
'plugin:@typescript-eslint/stylistic-type-checked',
|
|
||||||
'plugin:react/recommended',
|
|
||||||
'plugin:react-hooks/recommended',
|
|
||||||
'plugin:jsx-a11y/recommended',
|
|
||||||
'plugin:import/recommended',
|
|
||||||
'plugin:import/typescript',
|
|
||||||
'plugin:promise/recommended',
|
|
||||||
'plugin:jsdoc/recommended-typescript',
|
|
||||||
'plugin:prettier/recommended',
|
|
||||||
],
|
|
||||||
|
|
||||||
parserOptions: {
|
|
||||||
project: true,
|
|
||||||
tsconfigRootDir: __dirname,
|
|
||||||
},
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
|
||||||
|
|
||||||
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
|
|
||||||
'@typescript-eslint/consistent-type-exports': 'error',
|
|
||||||
'@typescript-eslint/consistent-type-imports': 'error',
|
|
||||||
"@typescript-eslint/prefer-nullish-coalescing": ['error', {ignorePrimitives: {boolean: true}}],
|
|
||||||
|
|
||||||
'jsdoc/require-jsdoc': 'off',
|
|
||||||
|
|
||||||
// Those rules set stricter rules for TS files
|
|
||||||
// to enforce better practices when converting from JS
|
|
||||||
'import/no-default-export': 'warn',
|
|
||||||
'react/prefer-stateless-function': 'warn',
|
|
||||||
'react/function-component-definition': ['error', { namedComponents: 'arrow-function' }],
|
|
||||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
|
||||||
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
|
||||||
'react/prop-types': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'**/__tests__/*.js',
|
|
||||||
'**/__tests__/*.jsx',
|
|
||||||
],
|
|
||||||
|
|
||||||
env: {
|
|
||||||
jest: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'streaming/**/*',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
'import/no-commonjs': 'off',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
---
|
|
||||||
name: Build Image for Deployment
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- '**pvz**'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: ghcr.io/catthehacker/ubuntu:act-22.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: docker/setup-buildx-action@v3
|
|
||||||
|
|
||||||
- name: Login to gitea container registry
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
registry: git.wir-sind-auch-menschen.de
|
|
||||||
username: alice-bot
|
|
||||||
password: ${{ secrets.GT_TOKEN }}
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
push: true
|
|
||||||
tags: git.wir-sind-auch-menschen.de/paravielfalt/mastodon:${{ gitea.ref_name }}
|
|
32
.github/CODEOWNERS
vendored
Normal file
32
.github/CODEOWNERS
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# CODEOWNERS for tootsuite/mastodon
|
||||||
|
|
||||||
|
# Translators
|
||||||
|
# To add translator, copy these lines, replace `fr` with appropriate language code and replace `@żelipapą` with user's GitHub nickname preceded by `@` sign or e-mail address.
|
||||||
|
# /app/javascript/mastodon/locales/fr.json @żelipapą
|
||||||
|
# /app/views/user_mailer/*.fr.html.erb @żelipapą
|
||||||
|
# /app/views/user_mailer/*.fr.text.erb @żelipapą
|
||||||
|
# /config/locales/*.fr.yml @żelipapą
|
||||||
|
# /config/locales/fr.yml @żelipapą
|
||||||
|
|
||||||
|
# Polish
|
||||||
|
/app/javascript/mastodon/locales/pl.json @m4sk1n
|
||||||
|
/app/views/user_mailer/*.pl.html.erb @m4sk1n
|
||||||
|
/app/views/user_mailer/*.pl.text.erb @m4sk1n
|
||||||
|
/config/locales/*.pl.yml @m4sk1n
|
||||||
|
/config/locales/pl.yml @m4sk1n
|
||||||
|
|
||||||
|
# French
|
||||||
|
/app/javascript/mastodon/locales/fr.json @aldarone
|
||||||
|
/app/javascript/mastodon/locales/whitelist_fr.json @aldarone
|
||||||
|
/app/views/user_mailer/*.fr.html.erb @aldarone
|
||||||
|
/app/views/user_mailer/*.fr.text.erb @aldarone
|
||||||
|
/config/locales/*.fr.yml @aldarone
|
||||||
|
/config/locales/fr.yml @aldarone
|
||||||
|
|
||||||
|
# Dutch
|
||||||
|
/app/javascript/mastodon/locales/nl.json @jeroenpraat
|
||||||
|
/app/javascript/mastodon/locales/whitelist_nl.json @jeroenpraat
|
||||||
|
/app/views/user_mailer/*.nl.html.erb @jeroenpraat
|
||||||
|
/app/views/user_mailer/*.nl.text.erb @jeroenpraat
|
||||||
|
/config/locales/*.nl.yml @jeroenpraat
|
||||||
|
/config/locales/nl.yml @jeroenpraat
|
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
patreon: mastodon
|
||||||
|
open_collective: mastodon
|
||||||
|
github: [Gargron]
|
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
27
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
name: Bug Report
|
||||||
|
about: If something isn't working as expected
|
||||||
|
labels: bug
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Make sure that you are submitting a new bug that was not previously reported or already fixed -->
|
||||||
|
|
||||||
|
<!-- Please use a concise and distinct title for the issue -->
|
||||||
|
|
||||||
|
### Expected behaviour
|
||||||
|
|
||||||
|
<!-- What should have happened? -->
|
||||||
|
|
||||||
|
### Actual behaviour
|
||||||
|
|
||||||
|
<!-- What happened? -->
|
||||||
|
|
||||||
|
### Steps to reproduce the problem
|
||||||
|
|
||||||
|
<!-- What were you trying to do? -->
|
||||||
|
|
||||||
|
### Specifications
|
||||||
|
|
||||||
|
<!-- What version or commit hash of Mastodon did you find this bug in? -->
|
||||||
|
|
||||||
|
<!-- If a front-end issue, what browser and operating systems were you using? -->
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Mastodon Meta Discussion Board
|
||||||
|
url: https://discourse.joinmastodon.org/
|
||||||
|
about: Please ask and answer questions here.
|
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
name: Feature Request
|
||||||
|
about: I have a suggestion
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Please use a concise and distinct title for the issue -->
|
||||||
|
|
||||||
|
<!-- Consider: Could it be implemented as a 3rd party app using the REST API instead? -->
|
||||||
|
|
||||||
|
### Pitch
|
||||||
|
|
||||||
|
<!-- Describe your idea for a feature. Make sure it has not already been suggested/implemented/turned down before -->
|
||||||
|
|
||||||
|
### Motivation
|
||||||
|
|
||||||
|
<!-- Why do you think this feature is needed? Who would benefit from it? -->
|
10
.github/ISSUE_TEMPLATE/support.md
vendored
Normal file
10
.github/ISSUE_TEMPLATE/support.md
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
name: Support
|
||||||
|
about: Ask for help with your deployment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
We primarily use GitHub as a bug and feature tracker. For usage questions, troubleshooting of deployments and other individual technical assistance, please use one of the resources below:
|
||||||
|
|
||||||
|
- https://discourse.joinmastodon.org
|
||||||
|
- #mastodon on irc.freenode.net
|
22
.github/dependabot.yml
vendored
Normal file
22
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: npm
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
open-pull-requests-limit: 99
|
||||||
|
allow:
|
||||||
|
- dependency-type: direct
|
||||||
|
|
||||||
|
- package-ecosystem: bundler
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
open-pull-requests-limit: 99
|
||||||
|
allow:
|
||||||
|
- dependency-type: direct
|
10
.github/stale.yml
vendored
Normal file
10
.github/stale.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
daysUntilStale: 120
|
||||||
|
daysUntilClose: 7
|
||||||
|
exemptLabels:
|
||||||
|
- security
|
||||||
|
staleLabel: wontfix
|
||||||
|
markComment: >
|
||||||
|
This issue has been automatically marked as stale because it has not had
|
||||||
|
recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
|
for your contributions.
|
||||||
|
only: pulls
|
34
.github/workflows/build-image.yml
vendored
Normal file
34
.github/workflows/build-image.yml
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
name: Build container image
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
tags:
|
||||||
|
- "*"
|
||||||
|
jobs:
|
||||||
|
build-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: docker/setup-buildx-action@v1
|
||||||
|
- uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- uses: docker/metadata-action@v3
|
||||||
|
id: meta
|
||||||
|
with:
|
||||||
|
images: tootsuite/mastodon
|
||||||
|
flavor: |
|
||||||
|
latest=false
|
||||||
|
tags: |
|
||||||
|
type=edge,branch=main
|
||||||
|
type=semver,pattern={{ raw }}
|
||||||
|
- uses: docker/build-push-action@v2
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
cache-from: type=registry,ref=tootsuite/mastodon:latest
|
||||||
|
cache-to: type=inline
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -40,10 +40,14 @@
|
||||||
|
|
||||||
# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose
|
# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose
|
||||||
/postgres
|
/postgres
|
||||||
/postgres14
|
|
||||||
/redis
|
/redis
|
||||||
/elasticsearch
|
/elasticsearch
|
||||||
|
|
||||||
|
# ignore Helm lockfile, dependency charts, and local values file
|
||||||
|
/chart/Chart.lock
|
||||||
|
/chart/charts/*.tgz
|
||||||
|
/chart/values.yaml
|
||||||
|
|
||||||
# Ignore Apple files
|
# Ignore Apple files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
|
106
.haml-lint.yml
106
.haml-lint.yml
|
@ -1,14 +1,108 @@
|
||||||
inherits_from: .haml-lint_todo.yml
|
# Whether to ignore frontmatter at the beginning of HAML documents for
|
||||||
|
# frameworks such as Jekyll/Middleman
|
||||||
|
skip_frontmatter: false
|
||||||
|
|
||||||
exclude:
|
exclude:
|
||||||
- 'vendor/**/*'
|
- 'vendor/**/*'
|
||||||
- lib/templates/haml/scaffold/_form.html.haml
|
- 'spec/**/*'
|
||||||
|
- 'lib/templates/**/*'
|
||||||
require:
|
- 'app/views/kaminari/**/*'
|
||||||
- ./lib/linter/haml_middle_dot.rb
|
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
AltText:
|
AltText:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
ClassAttributeWithStaticValue:
|
||||||
enabled: true
|
enabled: true
|
||||||
MiddleDot:
|
|
||||||
|
ClassesBeforeIds:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
ConsecutiveComments:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
ConsecutiveSilentScripts:
|
||||||
|
enabled: true
|
||||||
|
max_consecutive: 2
|
||||||
|
|
||||||
|
EmptyObjectReference:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
EmptyScript:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
FinalNewline:
|
||||||
|
enabled: true
|
||||||
|
present: true
|
||||||
|
|
||||||
|
HtmlAttributes:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
ImplicitDiv:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
LeadingCommentSpace:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
LineLength:
|
||||||
|
enabled: false
|
||||||
|
max: 80
|
||||||
|
|
||||||
|
MultilinePipe:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
MultilineScript:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
ObjectReferenceAttributes:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
RuboCop:
|
||||||
|
enabled: true
|
||||||
|
# These cops are incredibly noisy when it comes to HAML templates, so we
|
||||||
|
# ignore them.
|
||||||
|
ignored_cops:
|
||||||
|
- Lint/BlockAlignment
|
||||||
|
- Lint/EndAlignment
|
||||||
|
- Lint/Void
|
||||||
|
- Metrics/BlockLength
|
||||||
|
- Metrics/LineLength
|
||||||
|
- Style/AlignParameters
|
||||||
|
- Style/BlockNesting
|
||||||
|
- Style/ElseAlignment
|
||||||
|
- Style/EndOfLine
|
||||||
|
- Style/FileName
|
||||||
|
- Style/FinalNewline
|
||||||
|
- Style/FrozenStringLiteralComment
|
||||||
|
- Style/IfUnlessModifier
|
||||||
|
- Style/IndentationWidth
|
||||||
|
- Style/Next
|
||||||
|
- Style/TrailingBlankLines
|
||||||
|
- Style/TrailingWhitespace
|
||||||
|
- Style/WhileUntilModifier
|
||||||
|
|
||||||
|
RubyComments:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
SpaceBeforeScript:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
SpaceInsideHashAttributes:
|
||||||
|
enabled: true
|
||||||
|
style: space
|
||||||
|
|
||||||
|
Indentation:
|
||||||
|
enabled: true
|
||||||
|
character: space # or tab
|
||||||
|
|
||||||
|
TagName:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
TrailingWhitespace:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
UnnecessaryInterpolation:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
UnnecessaryStringOutput:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
# This configuration was generated by
|
|
||||||
# `haml-lint --auto-gen-config`
|
|
||||||
# on 2023-07-20 09:47:50 -0400 using Haml-Lint version 0.48.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: 951
|
|
||||||
LineLength:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Offense count: 22
|
|
||||||
UnnecessaryStringOutput:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Offense count: 57
|
|
||||||
RuboCop:
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# Offense count: 3
|
|
||||||
ViewLength:
|
|
||||||
exclude:
|
|
||||||
- 'app/views/admin/accounts/show.html.haml'
|
|
||||||
- 'app/views/admin/reports/show.html.haml'
|
|
||||||
- 'app/views/disputes/strikes/show.html.haml'
|
|
||||||
|
|
||||||
# Offense count: 32
|
|
||||||
InstanceVariables:
|
|
||||||
exclude:
|
|
||||||
- 'app/views/admin/reports/_actions.html.haml'
|
|
||||||
- 'app/views/admin/roles/_form.html.haml'
|
|
||||||
- 'app/views/admin/webhooks/_form.html.haml'
|
|
||||||
- 'app/views/auth/registrations/_status.html.haml'
|
|
||||||
- 'app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml'
|
|
||||||
- 'app/views/authorize_interactions/_post_follow_actions.html.haml'
|
|
||||||
- 'app/views/invites/_form.html.haml'
|
|
||||||
- 'app/views/relationships/_account.html.haml'
|
|
||||||
- 'app/views/shared/_og.html.haml'
|
|
||||||
|
|
||||||
# Offense count: 3
|
|
||||||
IdNames:
|
|
||||||
exclude:
|
|
||||||
- 'app/views/authorize_interactions/error.html.haml'
|
|
||||||
- 'app/views/oauth/authorizations/error.html.haml'
|
|
||||||
- 'app/views/shared/_error_messages.html.haml'
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
yarn lint-staged
|
|
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
20.7
|
12
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
|
||||||
#
|
|
||||||
# If you find yourself ignoring temporary files generated by your text editor
|
|
||||||
# or operating system, you probably want to add a global ignore instead:
|
|
||||||
# git config --global core.excludesfile '~/.gitignore_global'
|
|
||||||
|
|
||||||
# Ignore bundler config and downloaded libraries.
|
|
||||||
/.bundle
|
|
||||||
/vendor/bundle
|
|
||||||
|
|
||||||
# Ignore the default SQLite database.
|
|
||||||
/db/*.sqlite3
|
|
||||||
/db/*.sqlite3-journal
|
|
||||||
|
|
||||||
# Ignore all logfiles and tempfiles.
|
|
||||||
.eslintcache
|
|
||||||
/log/*
|
|
||||||
!/log/.keep
|
|
||||||
/tmp
|
|
||||||
/coverage
|
|
||||||
/public/system
|
|
||||||
/public/assets
|
|
||||||
/public/packs
|
|
||||||
/public/packs-test
|
|
||||||
.env
|
|
||||||
.env.production
|
|
||||||
.env.development
|
|
||||||
/node_modules/
|
|
||||||
/build/
|
|
||||||
|
|
||||||
# Ignore Vagrant files
|
|
||||||
.vagrant/
|
|
||||||
|
|
||||||
# Ignore Capistrano customizations
|
|
||||||
/config/deploy/*
|
|
||||||
|
|
||||||
# Ignore IDE files
|
|
||||||
.vscode/
|
|
||||||
.idea/
|
|
||||||
|
|
||||||
# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose
|
|
||||||
/postgres
|
|
||||||
/postgres14
|
|
||||||
/redis
|
|
||||||
/elasticsearch
|
|
||||||
|
|
||||||
# Ignore Apple files
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# Ignore vim files
|
|
||||||
*~
|
|
||||||
*.swp
|
|
||||||
|
|
||||||
# Ignore log files
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Ignore Docker option files
|
|
||||||
docker-compose.override.yml
|
|
||||||
|
|
||||||
# Ignore emoji map file
|
|
||||||
/app/javascript/mastodon/features/emoji/emoji_map.json
|
|
||||||
|
|
||||||
# Ignore locale files
|
|
||||||
/app/javascript/mastodon/locales/*.json
|
|
||||||
/config/locales
|
|
||||||
|
|
||||||
# Ignore vendored CSS reset
|
|
||||||
app/javascript/styles/mastodon/reset.scss
|
|
||||||
|
|
||||||
# Ignore Javascript pending https://github.com/mastodon/mastodon/pull/23631
|
|
||||||
*.js
|
|
||||||
*.jsx
|
|
||||||
|
|
||||||
# Ignore HTML till cleaned and included in CI
|
|
||||||
*.html
|
|
||||||
|
|
||||||
# Ignore the generated AUTHORS.md
|
|
||||||
AUTHORS.md
|
|
|
@ -1,4 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
singleQuote: true,
|
|
||||||
jsxSingleQuote: true
|
|
||||||
}
|
|
2
.profile
2
.profile
|
@ -1 +1 @@
|
||||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio:/app/.apt/usr/lib/x86_64-linux-gnu/openblas-pthread
|
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio
|
||||||
|
|
385
.rubocop.yml
385
.rubocop.yml
|
@ -1,202 +1,301 @@
|
||||||
# Can be removed once all rules are addressed or moved to this file as documented overrides
|
|
||||||
inherit_from: .rubocop_todo.yml
|
|
||||||
|
|
||||||
# Used for merging with exclude lists with .rubocop_todo.yml
|
|
||||||
inherit_mode:
|
|
||||||
merge:
|
|
||||||
- Exclude
|
|
||||||
|
|
||||||
require:
|
require:
|
||||||
- rubocop-rails
|
- rubocop-rails
|
||||||
- rubocop-rspec
|
|
||||||
- rubocop-performance
|
|
||||||
- rubocop-capybara
|
|
||||||
- ./lib/linter/rubocop_middle_dot
|
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 3.0 # Set to minimum supported version of CI
|
TargetRubyVersion: 2.4
|
||||||
DisplayCopNames: true
|
|
||||||
DisplayStyleGuide: true
|
|
||||||
ExtraDetails: true
|
|
||||||
UseCache: true
|
|
||||||
CacheRootDirectory: tmp
|
|
||||||
NewCops: enable # Opt-in to newly added rules
|
|
||||||
Exclude:
|
Exclude:
|
||||||
- db/schema.rb
|
- 'spec/**/*'
|
||||||
- 'bin/*'
|
- 'db/**/*'
|
||||||
- 'node_modules/**/*'
|
- 'app/views/**/*'
|
||||||
- 'Vagrantfile'
|
- 'config/**/*'
|
||||||
- 'vendor/**/*'
|
- 'bin/*'
|
||||||
- 'lib/json_ld/*' # Generated files
|
- 'Rakefile'
|
||||||
- 'lib/templates/**/*'
|
- 'node_modules/**/*'
|
||||||
|
- 'Vagrantfile'
|
||||||
|
- 'vendor/**/*'
|
||||||
|
- 'lib/json_ld/*'
|
||||||
|
- 'lib/templates/**/*'
|
||||||
|
|
||||||
# Reason: Prefer Hashes without extreme indentation
|
Bundler/OrderedGems:
|
||||||
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation
|
Enabled: false
|
||||||
Layout/FirstHashElementIndentation:
|
|
||||||
EnforcedStyle: consistent
|
|
||||||
|
|
||||||
# Reason: Currently disabled in .rubocop_todo.yml
|
Layout/AccessModifierIndentation:
|
||||||
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength
|
EnforcedStyle: indent
|
||||||
Layout/LineLength:
|
|
||||||
Max: 320 # Default of 120 causes a duplicate entry in generated todo file
|
Layout/EmptyLineAfterMagicComment:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/EmptyLineAfterGuardClause:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Layout/EmptyLinesAroundAttributeAccessor:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/HashAlignment:
|
||||||
|
Enabled: false
|
||||||
|
# EnforcedHashRocketStyle: table
|
||||||
|
# EnforcedColonStyle: table
|
||||||
|
|
||||||
|
Layout/SpaceAroundMethodCallOperator:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Layout/SpaceInsideHashLiteralBraces:
|
||||||
|
EnforcedStyle: space
|
||||||
|
|
||||||
|
Lint/DeprecatedOpenSSLConstant:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/DuplicateElsifCondition:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/MixedRegexpCaptureTypes:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/RaiseException:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Lint/StructNewOverride:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier
|
|
||||||
Lint/UselessAccessModifier:
|
Lint/UselessAccessModifier:
|
||||||
ContextCreatingMethods:
|
ContextCreatingMethods:
|
||||||
- class_methods
|
- 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:
|
Metrics/AbcSize:
|
||||||
|
Max: 100
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/mastodon/cli/*.rb'
|
- 'lib/mastodon/*_cli.rb'
|
||||||
- db/*migrate/**/*
|
|
||||||
|
Metrics/BlockLength:
|
||||||
|
Max: 55
|
||||||
|
Exclude:
|
||||||
|
- 'lib/tasks/**/*'
|
||||||
|
- 'lib/mastodon/*_cli.rb'
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocknesting
|
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
|
Max: 3
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/mastodon/cli/*.rb'
|
- 'lib/mastodon/*_cli.rb'
|
||||||
|
|
||||||
|
Metrics/ClassLength:
|
||||||
|
CountComments: false
|
||||||
|
Max: 400
|
||||||
|
Exclude:
|
||||||
|
- 'lib/mastodon/*_cli.rb'
|
||||||
|
|
||||||
# Reason: Currently disabled in .rubocop_todo.yml
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity
|
|
||||||
Metrics/CyclomaticComplexity:
|
Metrics/CyclomaticComplexity:
|
||||||
|
Max: 25
|
||||||
Exclude:
|
Exclude:
|
||||||
- lib/mastodon/cli/*.rb
|
- 'lib/mastodon/*_cli.rb'
|
||||||
- db/*migrate/**/*
|
|
||||||
|
Layout/LineLength:
|
||||||
|
AllowURI: true
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/MethodLength:
|
||||||
|
CountComments: false
|
||||||
|
Max: 65
|
||||||
|
Exclude:
|
||||||
|
- 'lib/mastodon/*_cli.rb'
|
||||||
|
|
||||||
|
Metrics/ModuleLength:
|
||||||
|
CountComments: false
|
||||||
|
Max: 200
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists
|
|
||||||
Metrics/ParameterLists:
|
Metrics/ParameterLists:
|
||||||
CountKeywordArgs: false
|
Max: 5
|
||||||
|
CountKeywordArgs: true
|
||||||
|
|
||||||
# Reason: Prevailing style is argument file paths
|
Metrics/PerceivedComplexity:
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath
|
Max: 25
|
||||||
Rails/FilePath:
|
|
||||||
EnforcedStyle: arguments
|
|
||||||
|
|
||||||
# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus
|
Naming/MemoizedInstanceVariableName:
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
|
Enabled: false
|
||||||
Rails/HttpStatus:
|
|
||||||
EnforcedStyle: numeric
|
Naming/MethodParameterName:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Rails:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Rails/ApplicationController:
|
||||||
|
Enabled: false
|
||||||
|
Exclude:
|
||||||
|
- 'app/controllers/well_known/**/*.rb'
|
||||||
|
|
||||||
|
Rails/BelongsTo:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/ContentTag:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/EnumHash:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Allowed in `tootctl` CLI code and in boot ENV checker
|
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
|
|
||||||
Rails/Exit:
|
Rails/Exit:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'config/boot.rb'
|
- 'lib/mastodon/*'
|
||||||
- 'lib/mastodon/cli/*.rb'
|
- 'lib/cli.rb'
|
||||||
|
|
||||||
# Reason: Some single letter camel case files shouldn't be split
|
Rails/FilePath:
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
|
Enabled: false
|
||||||
RSpec/FilePath:
|
|
||||||
CustomTransform:
|
|
||||||
ActivityPub: activitypub # Ignore the snake_case due to the amount of files to rename
|
|
||||||
DeepL: deepl
|
|
||||||
FetchOEmbedService: fetch_oembed_service
|
|
||||||
JsonLdHelper: jsonld_helper
|
|
||||||
OEmbedController: oembed_controller
|
|
||||||
OStatus: ostatus
|
|
||||||
NodeInfoController: nodeinfo_controller # NodeInfo isn't snake_cased for any of the instances
|
|
||||||
Exclude:
|
|
||||||
- 'spec/config/initializers/rack_attack_spec.rb' # namespaces usually have separate folder
|
|
||||||
- 'spec/lib/sanitize_config_spec.rb' # namespaces usually have separate folder
|
|
||||||
|
|
||||||
# Reason:
|
Rails/HasAndBelongsToMany:
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject
|
Enabled: false
|
||||||
RSpec/NamedSubject:
|
|
||||||
EnforcedStyle: named_only
|
|
||||||
|
|
||||||
# Reason: Prevailing style choice
|
Rails/HasManyOrHasOneDependent:
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot
|
Enabled: false
|
||||||
RSpec/NotToNot:
|
|
||||||
EnforcedStyle: to_not
|
|
||||||
|
|
||||||
# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus
|
Rails/HelperInstanceVariable:
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
|
Enabled: false
|
||||||
RSpec/Rails/HttpStatus:
|
|
||||||
EnforcedStyle: numeric
|
Rails/HttpStatus:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/IndexBy:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/InverseOf:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/LexicallyScopedActionFilter:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/OutputSafety:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Rails/RakeEnvironment:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/RedundantForeignKey:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/SkipsModelValidations:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Rails/UniqueValidationWithoutIndex:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/AccessorGrouping:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/AccessModifierDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/ArrayCoercion:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/BisectedAttrAccessor:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/CaseLikeIf:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren
|
|
||||||
Style/ClassAndModuleChildren:
|
Style/ClassAndModuleChildren:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Classes mostly self-document with their names
|
Style/CollectionMethods:
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation
|
Enabled: true
|
||||||
|
PreferredMethods:
|
||||||
|
find_all: 'select'
|
||||||
|
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Enforce modern Ruby style
|
Style/DoubleNegation:
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
|
Enabled: true
|
||||||
Style/HashSyntax:
|
|
||||||
EnforcedStyle: ruby19_no_mixed_keys
|
|
||||||
|
|
||||||
# Reason:
|
Style/ExpandPathArguments:
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals
|
Enabled: false
|
||||||
Style/NumericLiterals:
|
|
||||||
AllowedPatterns:
|
Style/ExponentialNotation:
|
||||||
- \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability
|
Enabled: true
|
||||||
|
|
||||||
|
Style/FormatString:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/FormatStringToken:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/FrozenStringLiteralComment:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/GuardClause:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/HashAsLastArrayItem:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/HashEachMethods:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashLikeCase:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashTransformKeys:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashTransformValues:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/IfUnlessModifier:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/InverseMethods:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/Lambda:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/MutableConstant:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters
|
|
||||||
Style/PercentLiteralDelimiters:
|
Style/PercentLiteralDelimiters:
|
||||||
PreferredDelimiters:
|
PreferredDelimiters:
|
||||||
'%i': '()'
|
'%i': '()'
|
||||||
'%w': '()'
|
'%w': '()'
|
||||||
|
|
||||||
# Reason: Prefer less indentation in conditional assignments
|
Style/PerlBackrefs:
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin
|
AutoCorrect: false
|
||||||
Style/RedundantBegin:
|
|
||||||
|
Style/RedundantAssignment:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RedundantFetchBlock:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantFileExtensionInRequire:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RedundantRegexpCharacterClass:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RedundantRegexpEscape:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/RedundantReturn:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
|
Style/RegexpLiteral:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Overridden to reduce implicit StandardError rescues
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror
|
|
||||||
Style/RescueStandardError:
|
Style/RescueStandardError:
|
||||||
EnforcedStyle: implicit
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Simplify some spec layouts
|
Style/SignalException:
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylesemicolon
|
Enabled: false
|
||||||
Style/Semicolon:
|
|
||||||
AllowAsExpressionSeparator: true
|
Style/SlicingWithRange:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
# Reason: Originally disabled for CodeClimate, and no config consensus has been found
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray
|
|
||||||
Style/SymbolArray:
|
Style/SymbolArray:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral
|
|
||||||
Style/TrailingCommaInArrayLiteral:
|
Style/TrailingCommaInArrayLiteral:
|
||||||
EnforcedStyleForMultiline: 'comma'
|
EnforcedStyleForMultiline: 'comma'
|
||||||
|
|
||||||
# Reason:
|
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral
|
|
||||||
Style/TrailingCommaInHashLiteral:
|
Style/TrailingCommaInHashLiteral:
|
||||||
EnforcedStyleForMultiline: 'comma'
|
EnforcedStyleForMultiline: 'comma'
|
||||||
|
|
||||||
Style/MiddleDot:
|
Style/UnpackFirst:
|
||||||
Enabled: true
|
Enabled: false
|
||||||
|
|
|
@ -1,842 +0,0 @@
|
||||||
# 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.56.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'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
|
||||||
# SupportedStyles: with_first_argument, with_fixed_indentation
|
|
||||||
Layout/ArgumentAlignment:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/cors.rb'
|
|
||||||
- 'config/initializers/session_store.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
|
|
||||||
# SupportedHashRocketStyles: key, separator, table
|
|
||||||
# SupportedColonStyles: key, separator, table
|
|
||||||
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
|
||||||
Layout/HashAlignment:
|
|
||||||
Exclude:
|
|
||||||
- 'config/environments/production.rb'
|
|
||||||
- 'config/initializers/rack_attack.rb'
|
|
||||||
- 'config/routes.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment.
|
|
||||||
Layout/LeadingCommentSpace:
|
|
||||||
Exclude:
|
|
||||||
- 'config/application.rb'
|
|
||||||
- 'config/initializers/3_omniauth.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: Max, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
|
|
||||||
# URISchemes: http, https
|
|
||||||
Layout/LineLength:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/account.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: require_no_space, require_space
|
|
||||||
Layout/SpaceInLambdaLiteral:
|
|
||||||
Exclude:
|
|
||||||
- 'config/environments/production.rb'
|
|
||||||
- 'config/initializers/content_security_policy.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: AllowComments, AllowEmptyLambdas.
|
|
||||||
Lint/EmptyBlock:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/api/v2/search_controller_spec.rb'
|
|
||||||
- 'spec/fabricators/access_token_fabricator.rb'
|
|
||||||
- 'spec/fabricators/conversation_fabricator.rb'
|
|
||||||
- 'spec/fabricators/system_key_fabricator.rb'
|
|
||||||
- 'spec/lib/activitypub/adapter_spec.rb'
|
|
||||||
- 'spec/models/user_role_spec.rb'
|
|
||||||
|
|
||||||
Lint/NonLocalExitFromIterator:
|
|
||||||
Exclude:
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Lint/OrAssignmentToConstant:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/sanitize_ext/sanitize_config.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
|
|
||||||
Lint/UnusedBlockArgument:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/content_security_policy.rb'
|
|
||||||
- 'config/initializers/doorkeeper.rb'
|
|
||||||
- 'config/initializers/paperclip.rb'
|
|
||||||
- 'config/initializers/simple_form.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Lint/UselessAssignment:
|
|
||||||
Exclude:
|
|
||||||
- 'app/services/activitypub/process_status_update_service.rb'
|
|
||||||
- 'config/initializers/3_omniauth.rb'
|
|
||||||
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
|
|
||||||
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
|
|
||||||
- 'spec/controllers/api/v1/favourites_controller_spec.rb'
|
|
||||||
- 'spec/controllers/concerns/account_controller_concern_spec.rb'
|
|
||||||
- 'spec/helpers/jsonld_helper_spec.rb'
|
|
||||||
- 'spec/models/account_spec.rb'
|
|
||||||
- 'spec/models/domain_block_spec.rb'
|
|
||||||
- 'spec/models/status_spec.rb'
|
|
||||||
- 'spec/models/user_spec.rb'
|
|
||||||
- 'spec/models/webauthn_credentials_spec.rb'
|
|
||||||
- 'spec/services/account_search_service_spec.rb'
|
|
||||||
- 'spec/services/post_status_service_spec.rb'
|
|
||||||
- 'spec/services/precompute_feed_service_spec.rb'
|
|
||||||
- 'spec/services/resolve_url_service_spec.rb'
|
|
||||||
- 'spec/views/statuses/show.html.haml_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
|
||||||
Metrics/AbcSize:
|
|
||||||
Max: 144
|
|
||||||
|
|
||||||
# Configuration parameters: CountBlocks, Max.
|
|
||||||
Metrics/BlockNesting:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/tasks/mastodon.rake'
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
||||||
Metrics/CyclomaticComplexity:
|
|
||||||
Max: 25
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
||||||
Metrics/PerceivedComplexity:
|
|
||||||
Max: 27
|
|
||||||
|
|
||||||
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
|
||||||
# SupportedStyles: snake_case, normalcase, non_integer
|
|
||||||
# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339, x86_64
|
|
||||||
Naming/VariableNumber:
|
|
||||||
Exclude:
|
|
||||||
- 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
|
|
||||||
- 'db/migrate/20180514140000_revert_index_change_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
|
|
||||||
- 'db/migrate/20190820003045_update_statuses_index.rb'
|
|
||||||
- 'db/migrate/20190823221802_add_local_index_to_statuses.rb'
|
|
||||||
- 'db/migrate/20200119112504_add_public_index_to_statuses.rb'
|
|
||||||
- 'spec/models/account_spec.rb'
|
|
||||||
- 'spec/models/domain_block_spec.rb'
|
|
||||||
- 'spec/models/user_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: SafeMultiline.
|
|
||||||
Performance/DeletePrefix:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/featured_tag.rb'
|
|
||||||
|
|
||||||
Performance/MapMethodChain:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/feed.rb'
|
|
||||||
- 'lib/mastodon/cli/maintenance.rb'
|
|
||||||
- 'spec/services/bulk_import_service_spec.rb'
|
|
||||||
- 'spec/services/import_service_spec.rb'
|
|
||||||
|
|
||||||
RSpec/AnyInstance:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/activitypub/inboxes_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/resets_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/settings/branding_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v1/media_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/sessions_controller_spec.rb'
|
|
||||||
- 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
|
|
||||||
- 'spec/controllers/settings/two_factor_authentication/recovery_codes_controller_spec.rb'
|
|
||||||
- 'spec/lib/request_spec.rb'
|
|
||||||
- 'spec/lib/status_filter_spec.rb'
|
|
||||||
- 'spec/models/account_spec.rb'
|
|
||||||
- 'spec/models/setting_spec.rb'
|
|
||||||
- 'spec/services/activitypub/process_collection_service_spec.rb'
|
|
||||||
- 'spec/validators/follow_limit_validator_spec.rb'
|
|
||||||
- 'spec/workers/activitypub/delivery_worker_spec.rb'
|
|
||||||
- 'spec/workers/web/push_notification_worker_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: CountAsOne.
|
|
||||||
RSpec/ExampleLength:
|
|
||||||
Max: 22
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: implicit, each, example
|
|
||||||
RSpec/HookArgument:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/api/v1/streaming_controller_spec.rb'
|
|
||||||
- 'spec/controllers/well_known/webfinger_controller_spec.rb'
|
|
||||||
- 'spec/helpers/instance_helper_spec.rb'
|
|
||||||
- 'spec/models/user_spec.rb'
|
|
||||||
- 'spec/rails_helper.rb'
|
|
||||||
- 'spec/serializers/activitypub/note_serializer_spec.rb'
|
|
||||||
- 'spec/serializers/activitypub/update_poll_serializer_spec.rb'
|
|
||||||
- 'spec/services/import_service_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: AssignmentOnly.
|
|
||||||
RSpec/InstanceVariable:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/api/v1/streaming_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/confirmations_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/passwords_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/sessions_controller_spec.rb'
|
|
||||||
- 'spec/controllers/concerns/export_controller_concern_spec.rb'
|
|
||||||
- 'spec/controllers/home_controller_spec.rb'
|
|
||||||
- 'spec/controllers/settings/two_factor_authentication/webauthn_credentials_controller_spec.rb'
|
|
||||||
- 'spec/controllers/statuses_cleanup_controller_spec.rb'
|
|
||||||
- 'spec/models/concerns/account_finder_concern_spec.rb'
|
|
||||||
- 'spec/models/concerns/account_interactions_spec.rb'
|
|
||||||
- 'spec/models/public_feed_spec.rb'
|
|
||||||
- 'spec/serializers/activitypub/note_serializer_spec.rb'
|
|
||||||
- 'spec/serializers/activitypub/update_poll_serializer_spec.rb'
|
|
||||||
- 'spec/services/remove_status_service_spec.rb'
|
|
||||||
- 'spec/services/search_service_spec.rb'
|
|
||||||
- 'spec/services/unblock_domain_service_spec.rb'
|
|
||||||
|
|
||||||
RSpec/LetSetup:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/action_logs_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/instances_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/reports/actions_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/statuses_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v1/filters_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v1/followed_tags_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
|
|
||||||
- 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/confirmations_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/passwords_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/sessions_controller_spec.rb'
|
|
||||||
- 'spec/controllers/follower_accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/following_accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/oauth/authorized_applications_controller_spec.rb'
|
|
||||||
- 'spec/controllers/oauth/tokens_controller_spec.rb'
|
|
||||||
- 'spec/controllers/settings/imports_controller_spec.rb'
|
|
||||||
- 'spec/lib/activitypub/activity/delete_spec.rb'
|
|
||||||
- 'spec/lib/vacuum/applications_vacuum_spec.rb'
|
|
||||||
- 'spec/lib/vacuum/preview_cards_vacuum_spec.rb'
|
|
||||||
- 'spec/models/account_spec.rb'
|
|
||||||
- 'spec/models/account_statuses_cleanup_policy_spec.rb'
|
|
||||||
- 'spec/models/canonical_email_block_spec.rb'
|
|
||||||
- 'spec/models/status_spec.rb'
|
|
||||||
- 'spec/models/user_spec.rb'
|
|
||||||
- 'spec/services/account_statuses_cleanup_service_spec.rb'
|
|
||||||
- 'spec/services/activitypub/fetch_featured_collection_service_spec.rb'
|
|
||||||
- 'spec/services/activitypub/fetch_remote_status_service_spec.rb'
|
|
||||||
- 'spec/services/activitypub/process_account_service_spec.rb'
|
|
||||||
- 'spec/services/activitypub/process_collection_service_spec.rb'
|
|
||||||
- 'spec/services/batched_remove_status_service_spec.rb'
|
|
||||||
- 'spec/services/block_domain_service_spec.rb'
|
|
||||||
- 'spec/services/bulk_import_service_spec.rb'
|
|
||||||
- 'spec/services/delete_account_service_spec.rb'
|
|
||||||
- 'spec/services/import_service_spec.rb'
|
|
||||||
- 'spec/services/notify_service_spec.rb'
|
|
||||||
- 'spec/services/remove_status_service_spec.rb'
|
|
||||||
- 'spec/services/report_service_spec.rb'
|
|
||||||
- 'spec/services/resolve_account_service_spec.rb'
|
|
||||||
- 'spec/services/suspend_account_service_spec.rb'
|
|
||||||
- 'spec/services/unallow_domain_service_spec.rb'
|
|
||||||
- 'spec/services/unsuspend_account_service_spec.rb'
|
|
||||||
- 'spec/workers/scheduler/user_cleanup_scheduler_spec.rb'
|
|
||||||
|
|
||||||
RSpec/MessageChain:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/api/v1/media_controller_spec.rb'
|
|
||||||
- 'spec/models/concerns/remotable_spec.rb'
|
|
||||||
- 'spec/models/session_activation_spec.rb'
|
|
||||||
- 'spec/models/setting_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: have_received, receive
|
|
||||||
RSpec/MessageSpies:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/helpers/admin/account_moderation_notes_helper_spec.rb'
|
|
||||||
- 'spec/lib/webfinger_resource_spec.rb'
|
|
||||||
- 'spec/models/admin/account_action_spec.rb'
|
|
||||||
- 'spec/models/concerns/remotable_spec.rb'
|
|
||||||
- 'spec/models/follow_request_spec.rb'
|
|
||||||
- 'spec/models/identity_spec.rb'
|
|
||||||
- 'spec/models/session_activation_spec.rb'
|
|
||||||
- 'spec/models/setting_spec.rb'
|
|
||||||
- 'spec/services/activitypub/fetch_replies_service_spec.rb'
|
|
||||||
- 'spec/services/activitypub/process_collection_service_spec.rb'
|
|
||||||
- 'spec/spec_helper.rb'
|
|
||||||
- 'spec/validators/status_length_validator_spec.rb'
|
|
||||||
|
|
||||||
RSpec/MultipleExpectations:
|
|
||||||
Max: 8
|
|
||||||
|
|
||||||
# Configuration parameters: AllowSubject.
|
|
||||||
RSpec/MultipleMemoizedHelpers:
|
|
||||||
Max: 21
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedGroups.
|
|
||||||
RSpec/NestedGroups:
|
|
||||||
Max: 6
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Rails/ApplicationController:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/health_controller.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: db/**/*.rb
|
|
||||||
Rails/CreateTableWithTimestamps:
|
|
||||||
Exclude:
|
|
||||||
- 'db/migrate/20170508230434_create_conversation_mutes.rb'
|
|
||||||
- 'db/migrate/20170823162448_create_status_pins.rb'
|
|
||||||
- 'db/migrate/20171116161857_create_list_accounts.rb'
|
|
||||||
- 'db/migrate/20180929222014_create_account_conversations.rb'
|
|
||||||
- 'db/migrate/20181007025445_create_pghero_space_stats.rb'
|
|
||||||
- 'db/migrate/20190103124649_create_scheduled_statuses.rb'
|
|
||||||
- 'db/migrate/20220824233535_create_status_trends.rb'
|
|
||||||
- 'db/migrate/20221006061337_create_preview_card_trends.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: Severity.
|
|
||||||
Rails/DuplicateAssociation:
|
|
||||||
Exclude:
|
|
||||||
- 'app/serializers/activitypub/collection_serializer.rb'
|
|
||||||
- 'app/serializers/activitypub/note_serializer.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/models/**/*.rb
|
|
||||||
Rails/HasAndBelongsToMany:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/concerns/account_associations.rb'
|
|
||||||
- 'app/models/preview_card.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/models/tag.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/models/**/*.rb
|
|
||||||
Rails/HasManyOrHasOneDependent:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/concerns/account_counters.rb'
|
|
||||||
- 'app/models/conversation.rb'
|
|
||||||
- 'app/models/custom_emoji.rb'
|
|
||||||
- 'app/models/custom_emoji_category.rb'
|
|
||||||
- 'app/models/domain_block.rb'
|
|
||||||
- 'app/models/invite.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
- 'app/models/web/push_subscription.rb'
|
|
||||||
|
|
||||||
Rails/I18nLocaleTexts:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/tasks/mastodon.rake'
|
|
||||||
- 'spec/helpers/flashes_helper_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/controllers/**/*.rb, app/mailers/**/*.rb
|
|
||||||
Rails/LexicallyScopedActionFilter:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/auth/passwords_controller.rb'
|
|
||||||
- 'app/controllers/auth/registrations_controller.rb'
|
|
||||||
- 'app/controllers/auth/sessions_controller.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Rails/NegateInclude:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/concerns/signature_verification.rb'
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
|
||||||
- 'app/lib/activitypub/activity/create.rb'
|
|
||||||
- 'app/lib/activitypub/activity/move.rb'
|
|
||||||
- 'app/lib/feed_manager.rb'
|
|
||||||
- 'app/lib/link_details_extractor.rb'
|
|
||||||
- 'app/models/concerns/attachmentable.rb'
|
|
||||||
- 'app/models/concerns/remotable.rb'
|
|
||||||
- 'app/models/custom_filter.rb'
|
|
||||||
- 'app/services/activitypub/process_status_update_service.rb'
|
|
||||||
- 'app/services/fetch_link_card_service.rb'
|
|
||||||
- 'app/services/search_service.rb'
|
|
||||||
- 'app/workers/web/push_notification_worker.rb'
|
|
||||||
- 'lib/paperclip/color_extractor.rb'
|
|
||||||
|
|
||||||
Rails/OutputSafety:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/simple_form.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: **/Rakefile, **/*.rake
|
|
||||||
Rails/RakeEnvironment:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/tasks/auto_annotate_models.rake'
|
|
||||||
- 'lib/tasks/db.rake'
|
|
||||||
- 'lib/tasks/emojis.rake'
|
|
||||||
- 'lib/tasks/mastodon.rake'
|
|
||||||
- 'lib/tasks/repo.rake'
|
|
||||||
- 'lib/tasks/statistics.rake'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: db/**/*.rb
|
|
||||||
Rails/ReversibleMigration:
|
|
||||||
Exclude:
|
|
||||||
- 'db/migrate/20160223164502_make_uris_nullable_in_statuses.rb'
|
|
||||||
- 'db/migrate/20161122163057_remove_unneeded_indexes.rb'
|
|
||||||
- 'db/migrate/20170205175257_remove_devices.rb'
|
|
||||||
- 'db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb'
|
|
||||||
- 'db/migrate/20170520145338_change_language_filter_to_opt_out.rb'
|
|
||||||
- 'db/migrate/20170609145826_remove_default_language_from_statuses.rb'
|
|
||||||
- 'db/migrate/20170711225116_fix_null_booleans.rb'
|
|
||||||
- 'db/migrate/20171129172043_add_index_on_stream_entries.rb'
|
|
||||||
- 'db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb'
|
|
||||||
- 'db/migrate/20171226094803_more_faster_index_on_notifications.rb'
|
|
||||||
- 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
|
|
||||||
- 'db/migrate/20180617162849_remove_unused_indexes.rb'
|
|
||||||
- 'db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: ForbiddenMethods, AllowedMethods.
|
|
||||||
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
|
|
||||||
Rails/SkipsModelValidations:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/admin/invites_controller.rb'
|
|
||||||
- 'app/controllers/concerns/session_tracking_concern.rb'
|
|
||||||
- 'app/models/concerns/account_merging.rb'
|
|
||||||
- 'app/models/concerns/expireable.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/models/trends/links.rb'
|
|
||||||
- 'app/models/trends/preview_card_batch.rb'
|
|
||||||
- 'app/models/trends/preview_card_provider_batch.rb'
|
|
||||||
- 'app/models/trends/status_batch.rb'
|
|
||||||
- 'app/models/trends/statuses.rb'
|
|
||||||
- 'app/models/trends/tag_batch.rb'
|
|
||||||
- 'app/models/trends/tags.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
- 'app/services/activitypub/process_status_update_service.rb'
|
|
||||||
- 'app/services/approve_appeal_service.rb'
|
|
||||||
- 'app/services/block_domain_service.rb'
|
|
||||||
- 'app/services/delete_account_service.rb'
|
|
||||||
- 'app/services/process_mentions_service.rb'
|
|
||||||
- 'app/services/unallow_domain_service.rb'
|
|
||||||
- 'app/services/unblock_domain_service.rb'
|
|
||||||
- 'app/services/update_status_service.rb'
|
|
||||||
- 'app/workers/activitypub/post_upgrade_worker.rb'
|
|
||||||
- 'app/workers/move_worker.rb'
|
|
||||||
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
|
|
||||||
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
|
|
||||||
- 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb'
|
|
||||||
- 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb'
|
|
||||||
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
|
|
||||||
- 'db/migrate/20170304202101_add_type_to_media_attachments.rb'
|
|
||||||
- 'db/migrate/20180528141303_fix_accounts_unique_index.rb'
|
|
||||||
- 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb'
|
|
||||||
- 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb'
|
|
||||||
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
|
|
||||||
- 'db/migrate/20191007013357_update_pt_locales.rb'
|
|
||||||
- 'db/migrate/20220316233212_update_kurdish_locales.rb'
|
|
||||||
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
|
|
||||||
- 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
|
|
||||||
- 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb'
|
|
||||||
- 'db/post_migrate/20220617202502_migrate_roles.rb'
|
|
||||||
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
|
|
||||||
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
|
|
||||||
- 'lib/mastodon/cli/accounts.rb'
|
|
||||||
- 'lib/mastodon/cli/main.rb'
|
|
||||||
- 'lib/mastodon/cli/maintenance.rb'
|
|
||||||
- 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/lib/activitypub/activity/follow_spec.rb'
|
|
||||||
- 'spec/services/follow_service_spec.rb'
|
|
||||||
- 'spec/services/update_account_service_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: db/**/*.rb
|
|
||||||
Rails/ThreeStateBooleanColumn:
|
|
||||||
Exclude:
|
|
||||||
- 'db/migrate/20160325130944_add_admin_to_users.rb'
|
|
||||||
- 'db/migrate/20161123093447_add_sensitive_to_statuses.rb'
|
|
||||||
- 'db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb'
|
|
||||||
- 'db/migrate/20170127165745_add_devise_two_factor_to_users.rb'
|
|
||||||
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
|
|
||||||
- 'db/migrate/20170330163835_create_imports.rb'
|
|
||||||
- 'db/migrate/20170905165803_add_local_to_statuses.rb'
|
|
||||||
- 'db/migrate/20181203021853_add_discoverable_to_accounts.rb'
|
|
||||||
- 'db/migrate/20190509164208_add_by_moderator_to_tombstone.rb'
|
|
||||||
- 'db/migrate/20190805123746_add_capabilities_to_tags.rb'
|
|
||||||
- 'db/migrate/20191212163405_add_hide_collections_to_accounts.rb'
|
|
||||||
- 'db/migrate/20200309150742_add_forwarded_to_reports.rb'
|
|
||||||
- 'db/migrate/20210609202149_create_login_activities.rb'
|
|
||||||
- 'db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb'
|
|
||||||
- 'db/migrate/20211031031021_create_preview_card_providers.rb'
|
|
||||||
- 'db/migrate/20211115032527_add_trendable_to_preview_cards.rb'
|
|
||||||
- 'db/migrate/20220202200743_add_trendable_to_accounts.rb'
|
|
||||||
- 'db/migrate/20220202200926_add_trendable_to_statuses.rb'
|
|
||||||
- 'db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.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'
|
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/models/**/*.rb
|
|
||||||
Rails/UnusedIgnoredColumns:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/account.rb'
|
|
||||||
- 'app/models/account_stat.rb'
|
|
||||||
- 'app/models/admin/action_log.rb'
|
|
||||||
- 'app/models/custom_filter.rb'
|
|
||||||
- 'app/models/email_domain_block.rb'
|
|
||||||
- 'app/models/report.rb'
|
|
||||||
- 'app/models/status_edit.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: exists, where
|
|
||||||
Rails/WhereExists:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/activitypub/inboxes_controller.rb'
|
|
||||||
- 'app/controllers/admin/email_domain_blocks_controller.rb'
|
|
||||||
- 'app/controllers/auth/registrations_controller.rb'
|
|
||||||
- 'app/lib/activitypub/activity/create.rb'
|
|
||||||
- 'app/lib/delivery_failure_tracker.rb'
|
|
||||||
- 'app/lib/feed_manager.rb'
|
|
||||||
- 'app/lib/status_cache_hydrator.rb'
|
|
||||||
- 'app/lib/suspicious_sign_in_detector.rb'
|
|
||||||
- 'app/models/concerns/account_interactions.rb'
|
|
||||||
- 'app/models/featured_tag.rb'
|
|
||||||
- 'app/models/poll.rb'
|
|
||||||
- 'app/models/session_activation.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
- 'app/policies/status_policy.rb'
|
|
||||||
- 'app/serializers/rest/announcement_serializer.rb'
|
|
||||||
- 'app/serializers/rest/tag_serializer.rb'
|
|
||||||
- 'app/services/activitypub/fetch_remote_status_service.rb'
|
|
||||||
- 'app/services/app_sign_up_service.rb'
|
|
||||||
- 'app/services/vote_service.rb'
|
|
||||||
- 'app/validators/reaction_validator.rb'
|
|
||||||
- 'app/validators/vote_validator.rb'
|
|
||||||
- 'app/workers/move_worker.rb'
|
|
||||||
- 'db/migrate/20190529143559_preserve_old_layout_for_existing_users.rb'
|
|
||||||
- 'lib/tasks/tests.rake'
|
|
||||||
- 'spec/models/account_spec.rb'
|
|
||||||
- 'spec/services/activitypub/process_collection_service_spec.rb'
|
|
||||||
- 'spec/services/purge_domain_service_spec.rb'
|
|
||||||
- 'spec/services/unallow_domain_service_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowOnConstant, AllowOnSelfClass.
|
|
||||||
Style/CaseEquality:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/trusted_proxies.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# 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 unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/CombinableLoops:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/form/custom_emoji_batch.rb'
|
|
||||||
- 'app/models/form/ip_block_batch.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'
|
|
||||||
- 'config/initializers/blacklists.rb'
|
|
||||||
- 'config/initializers/cache_buster.rb'
|
|
||||||
- 'config/initializers/content_security_policy.rb'
|
|
||||||
- 'config/initializers/devise.rb'
|
|
||||||
- 'config/initializers/paperclip.rb'
|
|
||||||
- 'config/initializers/vapid.rb'
|
|
||||||
- 'lib/mastodon/premailer_webpack_strategy.rb'
|
|
||||||
- 'lib/mastodon/redis_config.rb'
|
|
||||||
- 'lib/tasks/repo.rake'
|
|
||||||
- 'spec/features/profile_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
|
||||||
# SupportedStyles: annotated, template, unannotated
|
|
||||||
# AllowedMethods: redirect
|
|
||||||
Style/FormatStringToken:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/privacy_policy.rb'
|
|
||||||
- 'config/initializers/devise.rb'
|
|
||||||
- 'lib/paperclip/color_extractor.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/GlobalStdStream:
|
|
||||||
Exclude:
|
|
||||||
- 'config/boot.rb'
|
|
||||||
- 'config/environments/development.rb'
|
|
||||||
- 'config/environments/production.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
|
||||||
Style/GuardClause:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/admin/confirmations_controller.rb'
|
|
||||||
- 'app/controllers/auth/confirmations_controller.rb'
|
|
||||||
- 'app/controllers/auth/passwords_controller.rb'
|
|
||||||
- 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
|
|
||||||
- '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/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'
|
|
||||||
- 'db/migrate/20170901141119_truncate_preview_cards.rb'
|
|
||||||
- 'db/post_migrate/20220704024901_migrate_settings_to_user_roles.rb'
|
|
||||||
- 'lib/devise/two_factor_ldap_authenticatable.rb'
|
|
||||||
- 'lib/devise/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'
|
|
||||||
- 'db/migrate/20181024224956_migrate_account_conversations.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/HashTransformValues:
|
|
||||||
Exclude:
|
|
||||||
- '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).
|
|
||||||
# Configuration parameters: InverseMethods, InverseBlocks.
|
|
||||||
Style/InverseMethods:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/custom_filter.rb'
|
|
||||||
- 'app/services/update_account_service.rb'
|
|
||||||
- 'spec/controllers/activitypub/replies_controller_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: line_count_dependent, lambda, literal
|
|
||||||
Style/Lambda:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/simple_form.rb'
|
|
||||||
- 'config/routes.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/MapToHash:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: literals, strict
|
|
||||||
Style/MutableConstant:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/tag.rb'
|
|
||||||
- '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'
|
|
||||||
- 'app/lib/webfinger.rb'
|
|
||||||
- 'app/services/block_domain_service.rb'
|
|
||||||
- 'app/services/fetch_resource_service.rb'
|
|
||||||
- 'app/workers/domain_block_worker.rb'
|
|
||||||
- '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
|
|
||||||
Style/PreferredHashMethods:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/paperclip.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/RedundantConstantBase:
|
|
||||||
Exclude:
|
|
||||||
- '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 safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowMultipleReturnValues.
|
|
||||||
Style/RedundantReturn:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/api/v1/directories_controller.rb'
|
|
||||||
- 'app/controllers/auth/confirmations_controller.rb'
|
|
||||||
- 'app/lib/ostatus/tag_manager.rb'
|
|
||||||
- 'app/models/form/import.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'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: only_raise, only_fail, semantic
|
|
||||||
Style/SignalException:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/devise/two_factor_ldap_authenticatable.rb'
|
|
||||||
- 'lib/devise/two_factor_pam_authenticatable.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/SingleArgumentDig:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/webpacker/manifest_extensions.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: require_parentheses, require_no_parentheses
|
|
||||||
Style/StabbyLambdaParentheses:
|
|
||||||
Exclude:
|
|
||||||
- 'config/environments/production.rb'
|
|
||||||
- 'config/initializers/content_security_policy.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/StderrPuts:
|
|
||||||
Exclude:
|
|
||||||
- 'config/boot.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 unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
|
|
||||||
# AllowedMethods: define_method, mail, respond_to
|
|
||||||
Style/SymbolProc:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/3_omniauth.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
|
|
||||||
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
|
||||||
Style/TernaryParentheses:
|
|
||||||
Exclude:
|
|
||||||
- 'config/environments/development.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: EnforcedStyle, MinSize, WordRegex.
|
|
||||||
# SupportedStyles: percent, brackets
|
|
||||||
Style/WordArray:
|
|
||||||
Exclude:
|
|
||||||
- 'app/helpers/languages_helper.rb'
|
|
||||||
- 'config/initializers/cors.rb'
|
|
||||||
- 'spec/controllers/settings/imports_controller_spec.rb'
|
|
||||||
- 'spec/models/form/import_spec.rb'
|
|
|
@ -1 +0,0 @@
|
||||||
mastodon
|
|
|
@ -1 +1 @@
|
||||||
3.2.3
|
2.7.2
|
||||||
|
|
37
.sass-lint.yml
Normal file
37
.sass-lint.yml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# Linter Documentation:
|
||||||
|
# https://github.com/sasstools/sass-lint/tree/v1.13.1/docs/options
|
||||||
|
|
||||||
|
files:
|
||||||
|
include: app/javascript/styles/**/*.scss
|
||||||
|
ignore:
|
||||||
|
- app/javascript/styles/mastodon/reset.scss
|
||||||
|
|
||||||
|
rules:
|
||||||
|
# Disallows
|
||||||
|
no-color-literals: 0
|
||||||
|
no-css-comments: 0
|
||||||
|
no-duplicate-properties: 0
|
||||||
|
no-ids: 0
|
||||||
|
no-important: 0
|
||||||
|
no-mergeable-selectors: 0
|
||||||
|
no-misspelled-properties: 0
|
||||||
|
no-qualifying-elements: 0
|
||||||
|
no-transition-all: 0
|
||||||
|
no-vendor-prefixes: 0
|
||||||
|
|
||||||
|
# Nesting
|
||||||
|
force-element-nesting: 0
|
||||||
|
force-attribute-nesting: 0
|
||||||
|
force-pseudo-nesting: 0
|
||||||
|
|
||||||
|
# Name Formats
|
||||||
|
class-name-format: 0
|
||||||
|
leading-zero: 0
|
||||||
|
|
||||||
|
# Style Guide
|
||||||
|
attribute-quotes: 0
|
||||||
|
hex-length: 0
|
||||||
|
indentation: 0
|
||||||
|
nesting-depth: 0
|
||||||
|
property-sort-order: 0
|
||||||
|
quotes: 0
|
|
@ -44,6 +44,3 @@ Gruntfile.js
|
||||||
# for specific ignore
|
# for specific ignore
|
||||||
!.svgo.yml
|
!.svgo.yml
|
||||||
!sass-lint/**/*.yml
|
!sass-lint/**/*.yml
|
||||||
|
|
||||||
# breaks lint-staged or generally anything using https://github.com/eemeli/yaml/issues/384
|
|
||||||
!**/yaml/dist/**/doc
|
|
||||||
|
|
1709
AUTHORS.md
1709
AUTHORS.md
File diff suppressed because it is too large
Load diff
25
Aptfile
25
Aptfile
|
@ -1,5 +1,28 @@
|
||||||
ffmpeg
|
ffmpeg
|
||||||
libopenblas0-pthread
|
libicu[0-9][0-9]
|
||||||
|
libicu-dev
|
||||||
|
libidn11
|
||||||
|
libidn11-dev
|
||||||
libpq-dev
|
libpq-dev
|
||||||
|
libprotobuf-dev
|
||||||
libxdamage1
|
libxdamage1
|
||||||
libxfixes3
|
libxfixes3
|
||||||
|
protobuf-compiler
|
||||||
|
zlib1g-dev
|
||||||
|
libcairo2
|
||||||
|
libcroco3
|
||||||
|
libdatrie1
|
||||||
|
libgdk-pixbuf2.0-0
|
||||||
|
libgraphite2-3
|
||||||
|
libharfbuzz0b
|
||||||
|
libpango-1.0-0
|
||||||
|
libpangocairo-1.0-0
|
||||||
|
libpangoft2-1.0-0
|
||||||
|
libpixman-1-0
|
||||||
|
librsvg2-2
|
||||||
|
libthai-data
|
||||||
|
libthai0
|
||||||
|
libvpx5
|
||||||
|
libxcb-render0
|
||||||
|
libxcb-shm0
|
||||||
|
libxrender1
|
||||||
|
|
4225
CHANGELOG.md
4225
CHANGELOG.md
File diff suppressed because it is too large
Load diff
|
@ -2,131 +2,45 @@
|
||||||
|
|
||||||
## Our Pledge
|
## Our Pledge
|
||||||
|
|
||||||
We as members, contributors, and leaders pledge to make participation in our
|
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||||
community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
||||||
identity and expression, level of experience, education, socio-economic status,
|
|
||||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
||||||
identity and orientation.
|
|
||||||
|
|
||||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
||||||
diverse, inclusive, and healthy community.
|
|
||||||
|
|
||||||
## Our Standards
|
## Our Standards
|
||||||
|
|
||||||
Examples of behavior that contributes to a positive environment for our
|
Examples of behavior that contributes to creating a positive environment include:
|
||||||
community include:
|
|
||||||
|
|
||||||
- Demonstrating empathy and kindness toward other people
|
* Using welcoming and inclusive language
|
||||||
- Being respectful of differing opinions, viewpoints, and experiences
|
* Being respectful of differing viewpoints and experiences
|
||||||
- Giving and gracefully accepting constructive feedback
|
* Gracefully accepting constructive criticism
|
||||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
* Focusing on what is best for the community
|
||||||
and learning from the experience
|
* Showing empathy towards other community members
|
||||||
- Focusing on what is best not just for us as individuals, but for the overall
|
|
||||||
community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
- The use of sexualized language or imagery, and sexual attention or advances of
|
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||||
any kind
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
* Public or private harassment
|
||||||
- Public or private harassment
|
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||||
- Publishing others' private information, such as a physical or email address,
|
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
without their explicit permission
|
|
||||||
- Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
## Our Responsibilities
|
||||||
|
|
||||||
Community leaders are responsible for clarifying and enforcing our standards of
|
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||||
acceptable behavior and will take appropriate and fair corrective action in
|
|
||||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
||||||
or harmful.
|
|
||||||
|
|
||||||
Community leaders have the right and responsibility to remove, edit, or reject
|
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
||||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
||||||
decisions when appropriate.
|
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
This Code of Conduct applies within all community spaces, and also applies when
|
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||||
an individual is officially representing the community in public spaces.
|
|
||||||
Examples of representing our community include using an official e-mail address,
|
|
||||||
posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event.
|
|
||||||
|
|
||||||
## Enforcement
|
## Enforcement
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eugen@zeonfederated.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||||
reported to the community leaders responsible for enforcement at
|
|
||||||
[hello@joinmastodon.org](mailto:hello@joinmastodon.org).
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||||
reporter of any incident.
|
|
||||||
|
|
||||||
## Enforcement Guidelines
|
|
||||||
|
|
||||||
Community leaders will follow these Community Impact Guidelines in determining
|
|
||||||
the consequences for any action they deem in violation of this Code of Conduct:
|
|
||||||
|
|
||||||
### 1. Correction
|
|
||||||
|
|
||||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
||||||
unprofessional or unwelcome in the community.
|
|
||||||
|
|
||||||
**Consequence**: A private, written warning from community leaders, providing
|
|
||||||
clarity around the nature of the violation and an explanation of why the
|
|
||||||
behavior was inappropriate. A public apology may be requested.
|
|
||||||
|
|
||||||
### 2. Warning
|
|
||||||
|
|
||||||
**Community Impact**: A violation through a single incident or series of
|
|
||||||
actions.
|
|
||||||
|
|
||||||
**Consequence**: A warning with consequences for continued behavior. No
|
|
||||||
interaction with the people involved, including unsolicited interaction with
|
|
||||||
those enforcing the Code of Conduct, for a specified period of time. This
|
|
||||||
includes avoiding interactions in community spaces as well as external channels
|
|
||||||
like social media. Violating these terms may lead to a temporary or permanent
|
|
||||||
ban.
|
|
||||||
|
|
||||||
### 3. Temporary Ban
|
|
||||||
|
|
||||||
**Community Impact**: A serious violation of community standards, including
|
|
||||||
sustained inappropriate behavior.
|
|
||||||
|
|
||||||
**Consequence**: A temporary ban from any sort of interaction or public
|
|
||||||
communication with the community for a specified period of time. No public or
|
|
||||||
private interaction with the people involved, including unsolicited interaction
|
|
||||||
with those enforcing the Code of Conduct, is allowed during this period.
|
|
||||||
Violating these terms may lead to a permanent ban.
|
|
||||||
|
|
||||||
### 4. Permanent Ban
|
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
|
||||||
community.
|
|
||||||
|
|
||||||
## Attribution
|
## Attribution
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||||
version 2.1, available at
|
|
||||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by
|
[homepage]: http://contributor-covenant.org
|
||||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
[version]: http://contributor-covenant.org/version/1/4/
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
|
||||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
|
||||||
[https://www.contributor-covenant.org/translations][translations].
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
|
||||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
|
||||||
[FAQ]: https://www.contributor-covenant.org/faq
|
|
||||||
[translations]: https://www.contributor-covenant.org/translations
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# Contributing
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
Thank you for considering contributing to Mastodon 🐘
|
Thank you for considering contributing to Mastodon 🐘
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ If your contributions are accepted into Mastodon, you can request to be paid thr
|
||||||
|
|
||||||
## Bug reports
|
## Bug reports
|
||||||
|
|
||||||
Bug reports and feature suggestions must use descriptive and concise titles and be submitted to [GitHub Issues](https://github.com/mastodon/mastodon/issues). Please use the search function to make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected.
|
Bug reports and feature suggestions must use descriptive and concise titles and be submitted to [GitHub Issues](https://github.com/tootsuite/mastodon/issues). Please use the search function to make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected.
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
|
|
||||||
|
@ -23,17 +24,9 @@ You can submit translations via [Crowdin](https://crowdin.com/project/mastodon).
|
||||||
|
|
||||||
## Pull requests
|
## Pull requests
|
||||||
|
|
||||||
**Please use clean, concise titles for your pull requests.** Unless the pull request is about refactoring code, updating dependencies or other internal tasks, assume that the person reading the pull request title is not a programmer or Mastodon developer, but instead a Mastodon user or server administrator, and **try to describe your change or fix from their perspective**. We use commit squashing, so the final commit in the main branch will carry the title of the pull request, and commits from the main branch are fed into the changelog. The changelog is separated into [keepachangelog.com categories](https://keepachangelog.com/en/1.0.0/), and while that spec does not prescribe how the entries ought to be named, for easier sorting, start your pull request titles using one of the verbs "Add", "Change", "Deprecate", "Remove", or "Fix" (present tense).
|
Please use clean, concise titles for your pull requests. We use commit squashing, so the final commit in the master branch will carry the title of the pull request.
|
||||||
|
|
||||||
Example:
|
The smaller the set of changes in the pull request is, the quicker it can be reviewed and merged. Splitting tasks into multiple smaller pull requests is often preferable.
|
||||||
|
|
||||||
| Not ideal | Better |
|
|
||||||
| ------------------------------------ | ------------------------------------------------------------- |
|
|
||||||
| Fixed NoMethodError in RemovalWorker | Fix nil error when removing statuses caused by race condition |
|
|
||||||
|
|
||||||
It is not always possible to phrase every change in such a manner, but it is desired.
|
|
||||||
|
|
||||||
**The smaller the set of changes in the pull request is, the quicker it can be reviewed and merged.** Splitting tasks into multiple smaller pull requests is often preferable.
|
|
||||||
|
|
||||||
**Pull requests that do not pass automated checks may not be reviewed**. In particular, you need to keep in mind:
|
**Pull requests that do not pass automated checks may not be reviewed**. In particular, you need to keep in mind:
|
||||||
|
|
||||||
|
@ -43,4 +36,4 @@ It is not always possible to phrase every change in such a manner, but it is des
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/documentation](https://github.com/mastodon/documentation).
|
The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/docs](https://source.joinmastodon.org/mastodon/docs).
|
||||||
|
|
1
Capfile
1
Capfile
|
@ -1,5 +1,4 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require 'capistrano/setup'
|
require 'capistrano/setup'
|
||||||
require 'capistrano/deploy'
|
require 'capistrano/deploy'
|
||||||
require 'capistrano/scm/git'
|
require 'capistrano/scm/git'
|
||||||
|
|
201
Dockerfile
201
Dockerfile
|
@ -1,105 +1,144 @@
|
||||||
# syntax=docker/dockerfile:1.4
|
FROM ubuntu:20.04 as build-dep
|
||||||
# This needs to be bookworm-slim because the Ruby image is built on bookworm-slim
|
|
||||||
ARG NODE_VERSION="20.6-bookworm-slim"
|
|
||||||
|
|
||||||
FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.3-slim as ruby
|
# Use bash for the shell
|
||||||
FROM node:${NODE_VERSION} as build
|
SHELL ["bash", "-c"]
|
||||||
|
|
||||||
COPY --link --from=ruby /opt/ruby /opt/ruby
|
# Install Node v12 (LTS)
|
||||||
|
ENV NODE_VER="12.20.0"
|
||||||
|
RUN ARCH= && \
|
||||||
|
dpkgArch="$(dpkg --print-architecture)" && \
|
||||||
|
case "${dpkgArch##*-}" in \
|
||||||
|
amd64) ARCH='x64';; \
|
||||||
|
ppc64el) ARCH='ppc64le';; \
|
||||||
|
s390x) ARCH='s390x';; \
|
||||||
|
arm64) ARCH='arm64';; \
|
||||||
|
armhf) ARCH='armv7l';; \
|
||||||
|
i386) ARCH='x86';; \
|
||||||
|
*) echo "unsupported architecture"; exit 1 ;; \
|
||||||
|
esac && \
|
||||||
|
echo "Etc/UTC" > /etc/localtime && \
|
||||||
|
apt update && \
|
||||||
|
apt -y install wget python && \
|
||||||
|
cd ~ && \
|
||||||
|
wget https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-linux-$ARCH.tar.gz && \
|
||||||
|
tar xf node-v$NODE_VER-linux-$ARCH.tar.gz && \
|
||||||
|
rm node-v$NODE_VER-linux-$ARCH.tar.gz && \
|
||||||
|
mv node-v$NODE_VER-linux-$ARCH /opt/node
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND="noninteractive" \
|
# Install jemalloc
|
||||||
PATH="${PATH}:/opt/ruby/bin"
|
ENV JE_VER="5.2.1"
|
||||||
|
RUN apt update && \
|
||||||
|
apt -y install make autoconf gcc g++ && \
|
||||||
|
cd ~ && \
|
||||||
|
wget https://github.com/jemalloc/jemalloc/archive/$JE_VER.tar.gz && \
|
||||||
|
tar xf $JE_VER.tar.gz && \
|
||||||
|
cd jemalloc-$JE_VER && \
|
||||||
|
./autogen.sh && \
|
||||||
|
./configure --prefix=/opt/jemalloc && \
|
||||||
|
make -j$(nproc) > /dev/null && \
|
||||||
|
make install_bin install_include install_lib && \
|
||||||
|
cd .. && rm -rf jemalloc-$JE_VER $JE_VER.tar.gz
|
||||||
|
|
||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
# Install Ruby
|
||||||
|
ENV RUBY_VER="2.7.2"
|
||||||
|
ENV CPPFLAGS="-I/opt/jemalloc/include"
|
||||||
|
ENV LDFLAGS="-L/opt/jemalloc/lib/"
|
||||||
|
RUN apt update && \
|
||||||
|
apt -y install build-essential \
|
||||||
|
bison libyaml-dev libgdbm-dev libreadline-dev \
|
||||||
|
libncurses5-dev libffi-dev zlib1g-dev libssl-dev && \
|
||||||
|
cd ~ && \
|
||||||
|
wget https://cache.ruby-lang.org/pub/ruby/${RUBY_VER%.*}/ruby-$RUBY_VER.tar.gz && \
|
||||||
|
tar xf ruby-$RUBY_VER.tar.gz && \
|
||||||
|
cd ruby-$RUBY_VER && \
|
||||||
|
./configure --prefix=/opt/ruby \
|
||||||
|
--with-jemalloc \
|
||||||
|
--with-shared \
|
||||||
|
--disable-install-doc && \
|
||||||
|
ln -s /opt/jemalloc/lib/* /usr/lib/ && \
|
||||||
|
make -j$(nproc) > /dev/null && \
|
||||||
|
make install && \
|
||||||
|
cd .. && rm -rf ruby-$RUBY_VER.tar.gz ruby-$RUBY_VER
|
||||||
|
|
||||||
|
ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin"
|
||||||
|
|
||||||
|
RUN npm install -g yarn && \
|
||||||
|
gem install bundler && \
|
||||||
|
apt update && \
|
||||||
|
apt -y install git libicu-dev libidn11-dev \
|
||||||
|
libpq-dev libprotobuf-dev protobuf-compiler
|
||||||
|
|
||||||
WORKDIR /opt/mastodon
|
|
||||||
COPY Gemfile* package.json yarn.lock /opt/mastodon/
|
COPY Gemfile* package.json yarn.lock /opt/mastodon/
|
||||||
|
|
||||||
# hadolint ignore=DL3008
|
RUN cd /opt/mastodon && \
|
||||||
RUN apt-get update && \
|
bundle config set --local deployment 'true' && \
|
||||||
apt-get -yq dist-upgrade && \
|
bundle config set --local without 'development test' && \
|
||||||
apt-get install -y --no-install-recommends build-essential \
|
bundle install -j$(nproc) && \
|
||||||
git \
|
yarn install --pure-lockfile
|
||||||
libicu-dev \
|
|
||||||
libidn-dev \
|
|
||||||
libpq-dev \
|
|
||||||
libjemalloc-dev \
|
|
||||||
zlib1g-dev \
|
|
||||||
libgdbm-dev \
|
|
||||||
libgmp-dev \
|
|
||||||
libssl-dev \
|
|
||||||
libyaml-0-2 \
|
|
||||||
ca-certificates \
|
|
||||||
libreadline8 \
|
|
||||||
python3 \
|
|
||||||
shared-mime-info && \
|
|
||||||
bundle config set --local deployment 'true' && \
|
|
||||||
bundle config set --local without 'development test' && \
|
|
||||||
bundle config set silence_root_warning true && \
|
|
||||||
bundle install -j"$(nproc)" && \
|
|
||||||
yarn install --pure-lockfile --production --network-timeout 600000 && \
|
|
||||||
yarn cache clean
|
|
||||||
|
|
||||||
FROM node:${NODE_VERSION}
|
FROM ubuntu:20.04
|
||||||
|
|
||||||
# Use those args to specify your own version flags & suffixes
|
# Copy over all the langs needed for runtime
|
||||||
ARG MASTODON_VERSION_PRERELEASE=""
|
COPY --from=build-dep /opt/node /opt/node
|
||||||
ARG MASTODON_VERSION_METADATA=""
|
COPY --from=build-dep /opt/ruby /opt/ruby
|
||||||
|
COPY --from=build-dep /opt/jemalloc /opt/jemalloc
|
||||||
|
|
||||||
ARG UID="991"
|
# Add more PATHs to the PATH
|
||||||
ARG GID="991"
|
ENV PATH="${PATH}:/opt/ruby/bin:/opt/node/bin:/opt/mastodon/bin"
|
||||||
|
|
||||||
COPY --link --from=ruby /opt/ruby /opt/ruby
|
# Create the mastodon user
|
||||||
|
ARG UID=991
|
||||||
|
ARG GID=991
|
||||||
|
RUN apt update && \
|
||||||
|
echo "Etc/UTC" > /etc/localtime && \
|
||||||
|
ln -s /opt/jemalloc/lib/* /usr/lib/ && \
|
||||||
|
apt install -y whois wget && \
|
||||||
|
addgroup --gid $GID mastodon && \
|
||||||
|
useradd -m -u $UID -g $GID -d /opt/mastodon mastodon && \
|
||||||
|
echo "mastodon:`head /dev/urandom | tr -dc A-Za-z0-9 | head -c 24 | mkpasswd -s -m sha-256`" | chpasswd
|
||||||
|
|
||||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
# Install mastodon runtime deps
|
||||||
|
RUN apt -y --no-install-recommends install \
|
||||||
|
libssl1.1 libpq5 imagemagick ffmpeg \
|
||||||
|
libicu66 libprotobuf17 libidn11 libyaml-0-2 \
|
||||||
|
file ca-certificates tzdata libreadline8 && \
|
||||||
|
apt -y install gcc && \
|
||||||
|
ln -s /opt/mastodon /mastodon && \
|
||||||
|
gem install bundler && \
|
||||||
|
rm -rf /var/cache && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND="noninteractive" \
|
# Add tini
|
||||||
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin"
|
ENV TINI_VERSION="0.19.0"
|
||||||
|
RUN dpkgArch="$(dpkg --print-architecture)" && \
|
||||||
# Ignoring these here since we don't want to pin any versions and the Debian image removes apt-get content after use
|
ARCH=$dpkgArch && \
|
||||||
# hadolint ignore=DL3008,DL3009
|
wget https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-$ARCH \
|
||||||
RUN apt-get update && \
|
https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-$ARCH.sha256sum && \
|
||||||
echo "Etc/UTC" > /etc/localtime && \
|
cat tini-$ARCH.sha256sum | sha256sum -c - && \
|
||||||
groupadd -g "${GID}" mastodon && \
|
mv tini-$ARCH /tini && rm tini-$ARCH.sha256sum && \
|
||||||
useradd -l -u "$UID" -g "${GID}" -m -d /opt/mastodon mastodon && \
|
chmod +x /tini
|
||||||
apt-get -y --no-install-recommends install whois \
|
|
||||||
wget \
|
|
||||||
procps \
|
|
||||||
libssl3 \
|
|
||||||
libpq5 \
|
|
||||||
imagemagick \
|
|
||||||
ffmpeg \
|
|
||||||
libjemalloc2 \
|
|
||||||
libicu72 \
|
|
||||||
libidn12 \
|
|
||||||
libyaml-0-2 \
|
|
||||||
file \
|
|
||||||
ca-certificates \
|
|
||||||
tzdata \
|
|
||||||
libreadline8 \
|
|
||||||
tini && \
|
|
||||||
ln -s /opt/mastodon /mastodon
|
|
||||||
|
|
||||||
# Note: no, cleaning here since Debian does this automatically
|
|
||||||
# See the file /etc/apt/apt.conf.d/docker-clean within the Docker image's filesystem
|
|
||||||
|
|
||||||
|
# Copy over mastodon source, and dependencies from building, and set permissions
|
||||||
COPY --chown=mastodon:mastodon . /opt/mastodon
|
COPY --chown=mastodon:mastodon . /opt/mastodon
|
||||||
COPY --chown=mastodon:mastodon --from=build /opt/mastodon /opt/mastodon
|
COPY --from=build-dep --chown=mastodon:mastodon /opt/mastodon /opt/mastodon
|
||||||
|
|
||||||
ENV RAILS_ENV="production" \
|
# Run mastodon services in prod mode
|
||||||
NODE_ENV="production" \
|
ENV RAILS_ENV="production"
|
||||||
RAILS_SERVE_STATIC_FILES="true" \
|
ENV NODE_ENV="production"
|
||||||
BIND="0.0.0.0" \
|
|
||||||
MASTODON_VERSION_PRERELEASE="${MASTODON_VERSION_PRERELEASE}" \
|
# Tell rails to serve static files
|
||||||
MASTODON_VERSION_METADATA="${MASTODON_VERSION_METADATA}"
|
ENV RAILS_SERVE_STATIC_FILES="true"
|
||||||
|
ENV BIND="0.0.0.0"
|
||||||
|
|
||||||
# Set the run user
|
# Set the run user
|
||||||
USER mastodon
|
USER mastodon
|
||||||
WORKDIR /opt/mastodon
|
|
||||||
|
|
||||||
# Precompile assets
|
# Precompile assets
|
||||||
RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile
|
RUN cd ~ && \
|
||||||
|
OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile && \
|
||||||
|
yarn cache clean
|
||||||
|
|
||||||
# Set the work dir and the container entry point
|
# Set the work dir and the container entry point
|
||||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
WORKDIR /opt/mastodon
|
||||||
|
ENTRYPOINT ["/tini", "--"]
|
||||||
EXPOSE 3000 4000
|
EXPOSE 3000 4000
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
## ActivityPub federation in Mastodon
|
|
||||||
|
|
||||||
Mastodon largely follows the ActivityPub server-to-server specification but it makes uses of some non-standard extensions, some of which are required for interacting with Mastodon at all.
|
|
||||||
|
|
||||||
Supported vocabulary: https://docs.joinmastodon.org/spec/activitypub/
|
|
||||||
|
|
||||||
### Required extensions
|
|
||||||
|
|
||||||
#### Webfinger
|
|
||||||
|
|
||||||
In Mastodon, users are identified by a `username` and `domain` pair (e.g., `Gargron@mastodon.social`).
|
|
||||||
This is used both for discovery and for unambiguously mentioning users across the fediverse. Furthermore, this is part of Mastodon's database design from its very beginnings.
|
|
||||||
|
|
||||||
As a result, Mastodon requires that each ActivityPub actor uniquely maps back to an `acct:` URI that can be resolved via WebFinger.
|
|
||||||
|
|
||||||
More information and examples are available at: https://docs.joinmastodon.org/spec/webfinger/
|
|
||||||
|
|
||||||
#### HTTP Signatures
|
|
||||||
|
|
||||||
In order to authenticate activities, Mastodon relies on HTTP Signatures, signing every `POST` and `GET` request to other ActivityPub implementations on behalf of the user authoring an activity (for `POST` requests) or an actor representing the Mastodon server itself (for most `GET` requests).
|
|
||||||
|
|
||||||
Mastodon requires all `POST` requests to be signed, and MAY require `GET` requests to be signed, depending on the configuration of the Mastodon server.
|
|
||||||
|
|
||||||
More information on HTTP Signatures, as well as examples, can be found here: https://docs.joinmastodon.org/spec/security/#http
|
|
||||||
|
|
||||||
### Optional extensions
|
|
||||||
|
|
||||||
- Linked-Data Signatures: https://docs.joinmastodon.org/spec/security/#ld
|
|
||||||
- Bearcaps: https://docs.joinmastodon.org/spec/bearcaps/
|
|
||||||
- Followers collection synchronization: https://codeberg.org/fediverse/fep/src/branch/main/fep/8fcf/fep-8fcf.md
|
|
||||||
- Search indexing consent for actors: https://codeberg.org/fediverse/fep/src/branch/main/fep/5feb/fep-5feb.md
|
|
256
Gemfile
256
Gemfile
|
@ -1,207 +1,161 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '>= 3.0.0'
|
ruby '>= 2.5.0', '< 3.0.0'
|
||||||
|
|
||||||
gem 'puma', '~> 6.3'
|
gem 'pkg-config', '~> 1.4'
|
||||||
gem 'rails', '~> 7.0'
|
|
||||||
|
gem 'puma', '~> 5.0'
|
||||||
|
gem 'rails', '~> 5.2.4.4'
|
||||||
gem 'sprockets', '~> 3.7.2'
|
gem 'sprockets', '~> 3.7.2'
|
||||||
gem 'thor', '~> 1.2'
|
gem 'thor', '~> 1.0'
|
||||||
gem 'rack', '~> 2.2.7'
|
gem 'rack', '~> 2.2.3'
|
||||||
|
|
||||||
gem 'haml-rails', '~>2.0'
|
gem 'hamlit-rails', '~> 0.2'
|
||||||
gem 'pg', '~> 1.5'
|
gem 'pg', '~> 1.2'
|
||||||
gem 'pghero'
|
gem 'makara', '~> 0.4'
|
||||||
gem 'dotenv-rails', '~> 2.8'
|
gem 'pghero', '~> 2.7'
|
||||||
|
gem 'dotenv-rails', '~> 2.7'
|
||||||
|
|
||||||
gem 'aws-sdk-s3', '~> 1.123', require: false
|
gem 'aws-sdk-s3', '~> 1.85', require: false
|
||||||
gem 'fog-core', '<= 2.4.0'
|
gem 'fog-core', '<= 2.1.0'
|
||||||
gem 'fog-openstack', '~> 0.3', require: false
|
gem 'fog-openstack', '~> 0.3', require: false
|
||||||
gem 'kt-paperclip', '~> 7.2'
|
gem 'paperclip', '~> 6.0'
|
||||||
gem 'md-paperclip-azure', '~> 2.2', require: false
|
|
||||||
gem 'blurhash', '~> 0.1'
|
gem 'blurhash', '~> 0.1'
|
||||||
|
|
||||||
gem 'active_model_serializers', '~> 0.10'
|
gem 'active_model_serializers', '~> 0.10'
|
||||||
gem 'addressable', '~> 2.8'
|
gem 'addressable', '~> 2.7'
|
||||||
gem 'bootsnap', '~> 1.16.0', require: false
|
gem 'bootsnap', '~> 1.5', require: false
|
||||||
gem 'browser'
|
gem 'browser'
|
||||||
gem 'charlock_holmes', '~> 0.7.7'
|
gem 'charlock_holmes', '~> 0.7.7'
|
||||||
gem 'chewy', '~> 7.3'
|
gem 'iso-639'
|
||||||
gem 'devise', '~> 4.9'
|
gem 'chewy', '~> 5.1'
|
||||||
gem 'devise-two-factor', '~> 4.1'
|
gem 'cld3', '~> 3.3.0'
|
||||||
|
gem 'devise', '~> 4.7'
|
||||||
|
gem 'devise-two-factor', '~> 3.1'
|
||||||
|
|
||||||
group :pam_authentication, optional: true do
|
group :pam_authentication, optional: true do
|
||||||
gem 'devise_pam_authenticatable2', '~> 9.2'
|
gem 'devise_pam_authenticatable2', '~> 9.2'
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'net-ldap', '~> 0.18'
|
gem 'net-ldap', '~> 0.16'
|
||||||
|
gem 'omniauth-cas', '~> 2.0'
|
||||||
# TODO: Point back at released omniauth-cas gem when PR merged
|
gem 'omniauth-saml', '~> 1.10'
|
||||||
# https://github.com/dlindahl/omniauth-cas/pull/68
|
gem 'omniauth', '~> 1.9'
|
||||||
gem 'omniauth-cas', github: 'stanhu/omniauth-cas', ref: '4211e6d05941b4a981f9a36b49ec166cecd0e271'
|
gem 'omniauth-rails_csrf_protection', '~> 0.1'
|
||||||
gem 'omniauth-saml', '~> 2.0'
|
|
||||||
gem 'omniauth_openid_connect', '~> 0.6.1'
|
|
||||||
gem 'omniauth', '~> 2.0'
|
|
||||||
gem 'omniauth-rails_csrf_protection', '~> 1.0'
|
|
||||||
|
|
||||||
gem 'color_diff', '~> 0.1'
|
gem 'color_diff', '~> 0.1'
|
||||||
gem 'discard', '~> 1.2'
|
gem 'discard', '~> 1.2'
|
||||||
gem 'doorkeeper', '~> 5.6'
|
gem 'doorkeeper', '~> 5.4'
|
||||||
gem 'ed25519', '~> 1.3'
|
gem 'ed25519', '~> 1.2'
|
||||||
gem 'fast_blank', '~> 1.0'
|
gem 'fast_blank', '~> 1.0'
|
||||||
gem 'fastimage'
|
gem 'fastimage'
|
||||||
gem 'hiredis', '~> 0.6'
|
gem 'hiredis', '~> 0.6'
|
||||||
gem 'redis-namespace', '~> 1.10'
|
gem 'redis-namespace', '~> 1.8'
|
||||||
|
gem 'health_check', git: 'https://github.com/ianheggie/health_check', ref: '0b799ead604f900ed50685e9b2d469cd2befba5b'
|
||||||
gem 'htmlentities', '~> 4.3'
|
gem 'htmlentities', '~> 4.3'
|
||||||
gem 'http', '~> 5.1'
|
gem 'http', '~> 4.4'
|
||||||
gem 'http_accept_language', '~> 2.1'
|
gem 'http_accept_language', '~> 2.1'
|
||||||
gem 'httplog', '~> 1.6.2'
|
gem 'httplog', '~> 1.4.3'
|
||||||
gem 'idn-ruby', require: 'idn'
|
gem 'idn-ruby', require: 'idn'
|
||||||
gem 'kaminari', '~> 1.2'
|
gem 'kaminari', '~> 1.2'
|
||||||
gem 'link_header', '~> 0.0'
|
gem 'link_header', '~> 0.0'
|
||||||
gem 'mime-types', '~> 3.5.0', require: 'mime/types/columnar'
|
gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar'
|
||||||
gem 'nokogiri', '~> 1.15'
|
gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b176939f851338d0a4971a532'
|
||||||
gem 'nsa'
|
gem 'nokogiri', '~> 1.10'
|
||||||
gem 'oj', '~> 3.14'
|
gem 'nsa', '~> 0.2'
|
||||||
gem 'ox', '~> 2.14'
|
gem 'oj', '~> 3.10'
|
||||||
|
gem 'ox', '~> 2.13'
|
||||||
gem 'parslet'
|
gem 'parslet'
|
||||||
gem 'public_suffix', '~> 5.0'
|
gem 'parallel', '~> 1.20'
|
||||||
gem 'pundit', '~> 2.3'
|
gem 'posix-spawn'
|
||||||
|
gem 'pundit', '~> 2.1'
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'rack-attack', '~> 6.6'
|
gem 'rack-attack', '~> 6.3'
|
||||||
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
gem 'rack-cors', '~> 1.1', require: 'rack/cors'
|
||||||
gem 'rails-i18n', '~> 7.0'
|
gem 'rails-i18n', '~> 5.1'
|
||||||
gem 'rails-settings-cached', '~> 0.6', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true'
|
gem 'rails-settings-cached', '~> 0.6'
|
||||||
gem 'redcarpet', '~> 3.6'
|
gem 'redis', '~> 4.2', require: ['redis', 'redis/connection/hiredis']
|
||||||
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
|
||||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||||
gem 'rqrcode', '~> 2.2'
|
gem 'rqrcode', '~> 1.1'
|
||||||
gem 'ruby-progressbar', '~> 1.13'
|
gem 'ruby-progressbar', '~> 1.10'
|
||||||
gem 'sanitize', '~> 6.0'
|
gem 'sanitize', '~> 5.2'
|
||||||
gem 'scenic', '~> 1.7'
|
gem 'scenic', '~> 1.5'
|
||||||
gem 'sidekiq', '~> 6.5'
|
gem 'sidekiq', '~> 6.1'
|
||||||
gem 'sidekiq-scheduler', '~> 5.0'
|
gem 'sidekiq-scheduler', '~> 3.0'
|
||||||
gem 'sidekiq-unique-jobs', '~> 7.1'
|
gem 'sidekiq-unique-jobs', '~> 6.0'
|
||||||
gem 'sidekiq-bulk', '~> 0.2.0'
|
gem 'sidekiq-bulk', '~>0.2.0'
|
||||||
gem 'simple-navigation', '~> 4.4'
|
gem 'simple-navigation', '~> 4.1'
|
||||||
gem 'simple_form', '~> 5.2'
|
gem 'simple_form', '~> 5.0'
|
||||||
gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
|
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
||||||
gem 'stoplight', '~> 3.0.1'
|
gem 'stoplight', '~> 2.2.1'
|
||||||
gem 'strong_migrations', '~> 0.8'
|
gem 'strong_migrations', '~> 0.7'
|
||||||
gem 'tty-prompt', '~> 0.23', require: false
|
gem 'tty-prompt', '~> 0.22', require: false
|
||||||
gem 'twitter-text', '~> 3.1.0'
|
gem 'twitter-text', '~> 1.14'
|
||||||
gem 'tzinfo-data', '~> 1.2023'
|
gem 'tzinfo-data', '~> 1.2020'
|
||||||
gem 'webpacker', '~> 5.4'
|
gem 'webpacker', '~> 5.2'
|
||||||
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
|
gem 'webpush'
|
||||||
gem 'webauthn', '~> 3.0'
|
gem 'webauthn', '~> 3.0.0.alpha1'
|
||||||
|
|
||||||
gem 'json-ld'
|
gem 'json-ld'
|
||||||
gem 'json-ld-preloaded', '~> 3.2'
|
gem 'json-ld-preloaded', '~> 3.1'
|
||||||
gem 'rdf-normalize', '~> 0.5'
|
gem 'rdf-normalize', '~> 0.4'
|
||||||
|
|
||||||
gem 'private_address_check', '~> 0.5'
|
group :development, :test do
|
||||||
|
gem 'fabrication', '~> 2.21'
|
||||||
|
gem 'fuubar', '~> 2.5'
|
||||||
|
gem 'i18n-tasks', '~> 0.9', require: false
|
||||||
|
gem 'pry-byebug', '~> 3.9'
|
||||||
|
gem 'pry-rails', '~> 0.3'
|
||||||
|
gem 'rspec-rails', '~> 4.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
group :production, :test do
|
||||||
|
gem 'private_address_check', '~> 0.5'
|
||||||
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
# Used to split testing into chunks in CI
|
gem 'capybara', '~> 3.33'
|
||||||
gem 'rspec_chunked', '~> 0.6'
|
|
||||||
|
|
||||||
# RSpec progress bar formatter
|
|
||||||
gem 'fuubar', '~> 2.5'
|
|
||||||
|
|
||||||
# Extra RSpec extenion methods and helpers for sidekiq
|
|
||||||
gem 'rspec-sidekiq', '~> 4.0'
|
|
||||||
|
|
||||||
# Browser integration testing
|
|
||||||
gem 'capybara', '~> 3.39'
|
|
||||||
gem 'selenium-webdriver'
|
|
||||||
|
|
||||||
# Used to reset the database between system tests
|
|
||||||
gem 'database_cleaner-active_record'
|
|
||||||
|
|
||||||
# Used to mock environment variables
|
|
||||||
gem 'climate_control', '~> 0.2'
|
gem 'climate_control', '~> 0.2'
|
||||||
|
gem 'faker', '~> 2.14'
|
||||||
# Generating fake data for specs
|
gem 'microformats', '~> 4.2'
|
||||||
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'
|
gem 'rails-controller-testing', '~> 1.0'
|
||||||
|
gem 'rspec-sidekiq', '~> 3.1'
|
||||||
# Validate schemas in specs
|
gem 'simplecov', '~> 0.19', require: false
|
||||||
gem 'json-schema', '~> 4.0'
|
gem 'webmock', '~> 3.10'
|
||||||
|
gem 'parallel_tests', '~> 3.4'
|
||||||
# Test harness fo rack components
|
gem 'rspec_junit_formatter', '~> 0.4'
|
||||||
gem 'rack-test', '~> 2.1'
|
|
||||||
|
|
||||||
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
|
|
||||||
gem 'simplecov', '~> 0.22', require: false
|
|
||||||
|
|
||||||
# Stub web requests for specs
|
|
||||||
gem 'webmock', '~> 3.18'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
# Code linting CLI and plugins
|
gem 'active_record_query_trace', '~> 1.8'
|
||||||
gem 'rubocop', require: false
|
gem 'annotate', '~> 3.1'
|
||||||
gem 'rubocop-capybara', require: false
|
|
||||||
gem 'rubocop-performance', require: false
|
|
||||||
gem 'rubocop-rails', require: false
|
|
||||||
gem 'rubocop-rspec', require: false
|
|
||||||
|
|
||||||
# Annotates modules with schema
|
|
||||||
gem 'annotate', '~> 3.2'
|
|
||||||
|
|
||||||
# Enhanced error message pages for development
|
|
||||||
gem 'better_errors', '~> 2.9'
|
gem 'better_errors', '~> 2.9'
|
||||||
gem 'binding_of_caller', '~> 1.0'
|
gem 'binding_of_caller', '~> 0.7'
|
||||||
|
gem 'bullet', '~> 6.1'
|
||||||
|
gem 'letter_opener', '~> 1.7'
|
||||||
|
gem 'letter_opener_web', '~> 1.4'
|
||||||
|
gem 'memory_profiler'
|
||||||
|
gem 'rubocop', '~> 1.3', require: false
|
||||||
|
gem 'rubocop-rails', '~> 2.8', require: false
|
||||||
|
gem 'brakeman', '~> 4.10', require: false
|
||||||
|
gem 'bundler-audit', '~> 0.7', require: false
|
||||||
|
|
||||||
# Preview mail in the browser
|
gem 'capistrano', '~> 3.14'
|
||||||
gem 'letter_opener', '~> 1.8'
|
|
||||||
gem 'letter_opener_web', '~> 2.0'
|
|
||||||
|
|
||||||
# Security analysis CLI tools
|
|
||||||
gem 'brakeman', '~> 6.0', require: false
|
|
||||||
gem 'bundler-audit', '~> 0.9', require: false
|
|
||||||
|
|
||||||
# Linter CLI for HAML files
|
|
||||||
gem 'haml_lint', require: false
|
|
||||||
|
|
||||||
# Deployment automation
|
|
||||||
gem 'capistrano', '~> 3.17'
|
|
||||||
gem 'capistrano-rails', '~> 1.6'
|
gem 'capistrano-rails', '~> 1.6'
|
||||||
gem 'capistrano-rbenv', '~> 2.2'
|
gem 'capistrano-rbenv', '~> 2.2'
|
||||||
gem 'capistrano-yarn', '~> 2.0'
|
gem 'capistrano-yarn', '~> 2.0'
|
||||||
|
|
||||||
# Validate missing i18n keys
|
gem 'stackprof'
|
||||||
gem 'i18n-tasks', '~> 1.0', require: false
|
|
||||||
end
|
|
||||||
|
|
||||||
group :development, :test do
|
|
||||||
# Profiling tools
|
|
||||||
gem 'memory_profiler', require: false
|
|
||||||
gem 'ruby-prof', require: false
|
|
||||||
gem 'stackprof', require: false
|
|
||||||
gem 'test-prof'
|
|
||||||
|
|
||||||
# RSpec runner for rails
|
|
||||||
gem 'rspec-rails', '~> 6.0'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
gem 'lograge', '~> 0.12'
|
gem 'lograge', '~> 0.11'
|
||||||
|
gem 'redis-rails', '~> 5.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'concurrent-ruby', require: false
|
gem 'concurrent-ruby', require: false
|
||||||
gem 'connection_pool', require: false
|
gem 'connection_pool', require: false
|
||||||
|
|
||||||
gem 'xorcist', '~> 1.1'
|
gem 'xorcist', '~> 1.1'
|
||||||
gem 'cocoon', '~> 1.2'
|
gem 'pluck_each', '~> 0.1.3'
|
||||||
|
|
||||||
gem 'net-http', '~> 0.3.2'
|
|
||||||
gem 'rubyzip', '~> 2.3'
|
|
||||||
|
|
||||||
gem 'hcaptcha', '~> 7.1'
|
|
||||||
|
|
||||||
gem 'mail', '~> 2.8'
|
|
||||||
|
|
1216
Gemfile.lock
1216
Gemfile.lock
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb
|
web: env PORT=3000 bundle exec puma -C config/puma.rb
|
||||||
sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq
|
sidekiq: env PORT=3000 bundle exec sidekiq
|
||||||
stream: env PORT=4000 yarn run start
|
stream: env PORT=4000 yarn run start
|
||||||
webpack: bin/webpack-dev-server
|
webpack: ./bin/webpack-dev-server --listen-host 0.0.0.0
|
||||||
|
|
100
README.md
100
README.md
|
@ -1,23 +1,95 @@
|
||||||
# Mastodon - Paravielfalt Edition
|
![Mastodon](https://i.imgur.com/NhZc40l.png)
|
||||||
|
========
|
||||||
|
|
||||||
Dieses Repository enthält den Quellcode für [paravielfalt.zone](https://paravielfalt.zone).
|
[![GitHub release](https://img.shields.io/github/release/tootsuite/mastodon.svg)][releases]
|
||||||
|
[![Build Status](https://img.shields.io/circleci/project/github/tootsuite/mastodon.svg)][circleci]
|
||||||
|
[![Code Climate](https://img.shields.io/codeclimate/maintainability/tootsuite/mastodon.svg)][code_climate]
|
||||||
|
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/mastodon/localized.svg)][crowdin]
|
||||||
|
[![Docker Pulls](https://img.shields.io/docker/pulls/tootsuite/mastodon.svg)][docker]
|
||||||
|
|
||||||
Die Instanz basiert auf Mastodon und ist vom offiziellen Quellcode-Repository geforkt: <https://github.com/mastodon/mastodon>.
|
[releases]: https://github.com/tootsuite/mastodon/releases
|
||||||
|
[circleci]: https://circleci.com/gh/tootsuite/mastodon
|
||||||
|
[code_climate]: https://codeclimate.com/github/tootsuite/mastodon
|
||||||
|
[crowdin]: https://crowdin.com/project/mastodon
|
||||||
|
[docker]: https://hub.docker.com/r/tootsuite/mastodon/
|
||||||
|
|
||||||
## Änderungsübersicht
|
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, 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)!
|
||||||
|
|
||||||
Gegenüber der Mastodon-Standardinstallation gibt es folgende Änderungen.
|
Click below to **learn more** in a video:
|
||||||
|
|
||||||
- Zeichenlimit von 500 auf 1500 Zeichen erhöht
|
[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo]
|
||||||
|
|
||||||
[Vollständige Liste aller Änderungen](https://git.wir-sind-auch-menschen.de/paravielfalt/mastodon/compare/stable-4.1...paravielfalt-4.1).
|
[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
|
||||||
|
|
||||||
## Neue Version bauen
|
## Navigation
|
||||||
|
|
||||||
```sh
|
- [Project homepage 🐘](https://joinmastodon.org)
|
||||||
git tag v4.2.0-pvz$(date '+%y%m%d%H%M')
|
- [Support the development via Patreon][patreon]
|
||||||
```
|
- [View sponsors](https://joinmastodon.org/sponsors)
|
||||||
|
- [Blog](https://blog.joinmastodon.org)
|
||||||
|
- [Documentation](https://docs.joinmastodon.org)
|
||||||
|
- [Browse Mastodon servers](https://joinmastodon.org/#getting-started)
|
||||||
|
- [Browse Mastodon apps](https://joinmastodon.org/apps)
|
||||||
|
|
||||||
```sh
|
[patreon]: https://www.patreon.com/mastodon
|
||||||
git push --tag
|
|
||||||
```
|
## Features
|
||||||
|
|
||||||
|
<img src="https://docs.joinmastodon.org/elephant.svg" 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**
|
||||||
|
|
||||||
|
See the 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 are looped - like vines!
|
||||||
|
|
||||||
|
**Safety and moderation tools**
|
||||||
|
|
||||||
|
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, resulting 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** 9.5+
|
||||||
|
- **Redis** 4+
|
||||||
|
- **Ruby** 2.5+
|
||||||
|
- **Node.js** 10.13+
|
||||||
|
|
||||||
|
The repository includes deployment configurations for **Docker and docker-compose**, but also a few specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. The [**stand-alone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.
|
||||||
|
|
||||||
|
A **Vagrant** configuration is included for development purposes.
|
||||||
|
|
||||||
|
## 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.freenode.net
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Copyright (C) 2016-2020 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/>.
|
||||||
|
|
4
Rakefile
4
Rakefile
|
@ -1,8 +1,6 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
require File.expand_path('config/application', __dir__)
|
require File.expand_path('../config/application', __FILE__)
|
||||||
|
|
||||||
Rails.application.load_tasks
|
Rails.application.load_tasks
|
||||||
|
|
24
SECURITY.md
24
SECURITY.md
|
@ -1,20 +1,12 @@
|
||||||
# Security Policy
|
# Security Policy
|
||||||
|
|
||||||
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)
|
|
||||||
- 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.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
A "vulnerability in Mastodon" is a vulnerability in the code distributed through our main source code repository on GitHub. Vulnerabilities that are specific to a given installation (e.g. misconfiguration) should be reported to the owner of that installation and not us.
|
|
||||||
|
|
||||||
## Supported Versions
|
## Supported Versions
|
||||||
|
|
||||||
| Version | Supported |
|
| Version | Supported |
|
||||||
| ------- | --------- |
|
| ------- | ------------------ |
|
||||||
| 4.2.x | Yes |
|
| 3.1.x | :white_check_mark: |
|
||||||
| 4.1.x | Yes |
|
| < 3.1 | :x: |
|
||||||
| < 4.1 | No |
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
hello@joinmastodon.org
|
||||||
|
|
125
Vagrantfile
vendored
125
Vagrantfile
vendored
|
@ -3,14 +3,16 @@
|
||||||
|
|
||||||
ENV["PORT"] ||= "3000"
|
ENV["PORT"] ||= "3000"
|
||||||
|
|
||||||
$provisionA = <<SCRIPT
|
$provision = <<SCRIPT
|
||||||
|
|
||||||
|
cd /vagrant # This is where the host folder/repo is mounted
|
||||||
|
|
||||||
# Add the yarn repo + yarn repo keys
|
# Add the yarn repo + yarn repo keys
|
||||||
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
||||||
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
||||||
|
|
||||||
# Add repo for NodeJS
|
# Add repo for NodeJS
|
||||||
curl -sL https://deb.nodesource.com/setup_16.x | sudo bash -
|
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
|
||||||
|
|
||||||
# Add firewall rule to redirect 80 to PORT and save
|
# Add firewall rule to redirect 80 to PORT and save
|
||||||
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
||||||
|
@ -31,111 +33,72 @@ sudo apt-get install \
|
||||||
redis-tools \
|
redis-tools \
|
||||||
postgresql \
|
postgresql \
|
||||||
postgresql-contrib \
|
postgresql-contrib \
|
||||||
|
protobuf-compiler \
|
||||||
|
yarn \
|
||||||
libicu-dev \
|
libicu-dev \
|
||||||
libidn11-dev \
|
libidn11-dev \
|
||||||
libreadline6-dev \
|
|
||||||
autoconf \
|
|
||||||
bison \
|
|
||||||
build-essential \
|
|
||||||
ffmpeg \
|
|
||||||
file \
|
|
||||||
gcc \
|
|
||||||
libffi-dev \
|
|
||||||
libgdbm-dev \
|
|
||||||
libjemalloc-dev \
|
|
||||||
libncurses5-dev \
|
|
||||||
libprotobuf-dev \
|
libprotobuf-dev \
|
||||||
libssl-dev \
|
libreadline-dev \
|
||||||
libyaml-dev \
|
libpam0g-dev \
|
||||||
pkg-config \
|
|
||||||
protobuf-compiler \
|
|
||||||
zlib1g-dev \
|
|
||||||
-y
|
-y
|
||||||
|
|
||||||
# Install rvm
|
# Install rvm
|
||||||
sudo apt-add-repository -y ppa:rael-gc/rvm
|
read RUBY_VERSION < .ruby-version
|
||||||
sudo apt-get install rvm -y
|
|
||||||
|
|
||||||
sudo usermod -a -G rvm $USER
|
gpg_command="gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB"
|
||||||
|
$($gpg_command)
|
||||||
|
if [ $? -ne 0 ];then
|
||||||
|
echo "GPG command failed, This prevented RVM from installing."
|
||||||
|
echo "Retrying once..." && $($gpg_command)
|
||||||
|
if [ $? -ne 0 ];then
|
||||||
|
echo "GPG failed for the second time, please ensure network connectivity."
|
||||||
|
echo "Exiting..." && exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
SCRIPT
|
curl -sSL https://raw.githubusercontent.com/rvm/rvm/stable/binscripts/rvm-installer | bash -s stable --ruby=$RUBY_VERSION
|
||||||
|
source /home/vagrant/.rvm/scripts/rvm
|
||||||
$provisionElasticsearch = <<SCRIPT
|
|
||||||
# Install Elastic Search
|
|
||||||
sudo apt install openjdk-17-jre-headless -y
|
|
||||||
sudo wget -O /usr/share/keyrings/elasticsearch.asc https://artifacts.elastic.co/GPG-KEY-elasticsearch
|
|
||||||
sudo sh -c 'echo "deb [signed-by=/usr/share/keyrings/elasticsearch.asc] https://artifacts.elastic.co/packages/7.x/apt stable main" > /etc/apt/sources.list.d/elastic-7.x.list'
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install elasticsearch -y
|
|
||||||
|
|
||||||
sudo systemctl daemon-reload
|
|
||||||
sudo systemctl enable --now elasticsearch
|
|
||||||
|
|
||||||
echo 'path.data: /var/lib/elasticsearch
|
|
||||||
path.logs: /var/log/elasticsearch
|
|
||||||
network.host: 0.0.0.0
|
|
||||||
http.port: 9200
|
|
||||||
discovery.seed_hosts: ["localhost"]
|
|
||||||
cluster.initial_master_nodes: ["node-1"]
|
|
||||||
xpack.security.enabled: false' > /etc/elasticsearch/elasticsearch.yml
|
|
||||||
|
|
||||||
sudo systemctl restart elasticsearch
|
|
||||||
|
|
||||||
# Install Kibana
|
|
||||||
sudo apt install kibana -y
|
|
||||||
sudo systemctl enable --now kibana
|
|
||||||
|
|
||||||
echo 'server.host: "0.0.0.0"
|
|
||||||
elasticsearch.hosts: ["http://localhost:9200"]' > /etc/kibana/kibana.yml
|
|
||||||
|
|
||||||
sudo systemctl restart kibana
|
|
||||||
|
|
||||||
SCRIPT
|
|
||||||
|
|
||||||
$provisionB = <<SCRIPT
|
|
||||||
|
|
||||||
source "/etc/profile.d/rvm.sh"
|
|
||||||
|
|
||||||
# Install Ruby
|
# Install Ruby
|
||||||
read RUBY_VERSION < /vagrant/.ruby-version
|
rvm reinstall ruby-$RUBY_VERSION --disable-binary
|
||||||
rvm install ruby-$RUBY_VERSION --disable-binary
|
|
||||||
|
|
||||||
# Configure database
|
# Configure database
|
||||||
sudo -u postgres createuser -U postgres vagrant -s
|
sudo -u postgres createuser -U postgres vagrant -s
|
||||||
sudo -u postgres createdb -U postgres mastodon_development
|
sudo -u postgres createdb -U postgres mastodon_development
|
||||||
|
|
||||||
cd /vagrant # This is where the host folder/repo is mounted
|
# Install gems and node modules
|
||||||
|
|
||||||
# Install gems
|
|
||||||
gem install bundler foreman
|
gem install bundler foreman
|
||||||
bundle install
|
bundle install
|
||||||
|
|
||||||
# Install node modules
|
|
||||||
sudo corepack enable
|
|
||||||
yarn set version classic
|
|
||||||
yarn install
|
yarn install
|
||||||
|
|
||||||
# Build Mastodon
|
# Build Mastodon
|
||||||
export RAILS_ENV=development
|
|
||||||
export $(cat ".env.vagrant" | xargs)
|
export $(cat ".env.vagrant" | xargs)
|
||||||
bundle exec rails db:setup
|
bundle exec rails db:setup
|
||||||
|
|
||||||
# Configure automatic loading of environment variable
|
# Configure automatic loading of environment variable
|
||||||
echo 'export RAILS_ENV=development' >> ~/.bash_profile
|
|
||||||
echo 'export $(cat "/vagrant/.env.vagrant" | xargs)' >> ~/.bash_profile
|
echo 'export $(cat "/vagrant/.env.vagrant" | xargs)' >> ~/.bash_profile
|
||||||
|
|
||||||
SCRIPT
|
SCRIPT
|
||||||
|
|
||||||
|
$start = <<SCRIPT
|
||||||
|
|
||||||
|
echo 'To start server'
|
||||||
|
echo ' $ vagrant ssh -c "cd /vagrant && foreman start"'
|
||||||
|
|
||||||
|
SCRIPT
|
||||||
|
|
||||||
VAGRANTFILE_API_VERSION = "2"
|
VAGRANTFILE_API_VERSION = "2"
|
||||||
|
|
||||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
|
|
||||||
config.vm.box = "ubuntu/focal64"
|
config.vm.box = "ubuntu/bionic64"
|
||||||
|
|
||||||
config.vm.provider :virtualbox do |vb|
|
config.vm.provider :virtualbox do |vb|
|
||||||
vb.name = "mastodon"
|
vb.name = "mastodon"
|
||||||
vb.customize ["modifyvm", :id, "--memory", "8192"]
|
vb.customize ["modifyvm", :id, "--memory", "2048"]
|
||||||
vb.customize ["modifyvm", :id, "--cpus", "3"]
|
# Increase the number of CPUs. Uncomment and adjust to
|
||||||
|
# increase performance
|
||||||
|
# vb.customize ["modifyvm", :id, "--cpus", "3"]
|
||||||
|
|
||||||
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
|
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
|
||||||
# https://github.com/mitchellh/vagrant/issues/1172
|
# https://github.com/mitchellh/vagrant/issues/1172
|
||||||
|
@ -145,6 +108,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
# Use "virtio" network interfaces for better performance.
|
# Use "virtio" network interfaces for better performance.
|
||||||
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
|
vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
|
||||||
vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
|
vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# This uses the vagrant-hostsupdater plugin, and lets you
|
# This uses the vagrant-hostsupdater plugin, and lets you
|
||||||
|
@ -162,7 +126,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.vm.networks.any? { |type, options| type == :private_network }
|
if config.vm.networks.any? { |type, options| type == :private_network }
|
||||||
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'actimeo=1']
|
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp', 'actimeo=1']
|
||||||
else
|
else
|
||||||
config.vm.synced_folder ".", "/vagrant"
|
config.vm.synced_folder ".", "/vagrant"
|
||||||
end
|
end
|
||||||
|
@ -171,20 +135,11 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
||||||
config.vm.network :forwarded_port, guest: 4000, host: 4000
|
config.vm.network :forwarded_port, guest: 4000, host: 4000
|
||||||
config.vm.network :forwarded_port, guest: 8080, host: 8080
|
config.vm.network :forwarded_port, guest: 8080, host: 8080
|
||||||
config.vm.network :forwarded_port, guest: 9200, host: 9200
|
|
||||||
config.vm.network :forwarded_port, guest: 9300, host: 9300
|
|
||||||
config.vm.network :forwarded_port, guest: 9243, host: 9243
|
|
||||||
config.vm.network :forwarded_port, guest: 5601, host: 5601
|
|
||||||
|
|
||||||
# Full provisioning script, only runs on first 'vagrant up' or with 'vagrant provision'
|
# Full provisioning script, only runs on first 'vagrant up' or with 'vagrant provision'
|
||||||
config.vm.provision :shell, inline: $provisionA, privileged: false, reset: true
|
config.vm.provision :shell, inline: $provision, privileged: false
|
||||||
# Run with elevated privileges for Elasticsearch installation
|
|
||||||
config.vm.provision :shell, inline: $provisionElasticsearch, privileged: true
|
|
||||||
config.vm.provision :shell, inline: $provisionB, privileged: false
|
|
||||||
|
|
||||||
config.vm.post_up_message = <<MESSAGE
|
# Start up script, runs on every 'vagrant up'
|
||||||
To start server
|
config.vm.provision :shell, inline: $start, run: 'always', privileged: false
|
||||||
$ vagrant ssh -c "cd /vagrant && foreman start"
|
|
||||||
MESSAGE
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
16
app.json
16
app.json
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "Mastodon",
|
"name": "Mastodon",
|
||||||
"description": "A GNU Social-compatible microblogging server",
|
"description": "A GNU Social-compatible microblogging server",
|
||||||
"repository": "https://github.com/mastodon/mastodon",
|
"repository": "https://github.com/tootsuite/mastodon",
|
||||||
"logo": "https://github.com/mastodon.png",
|
"logo": "https://github.com/tootsuite.png",
|
||||||
"env": {
|
"env": {
|
||||||
"HEROKU": {
|
"HEROKU": {
|
||||||
"description": "Leave this as true",
|
"description": "Leave this as true",
|
||||||
|
@ -79,13 +79,8 @@
|
||||||
"description": "SMTP server certificate verification mode. Defaults is 'peer'.",
|
"description": "SMTP server certificate verification mode. Defaults is 'peer'.",
|
||||||
"required": false
|
"required": false
|
||||||
},
|
},
|
||||||
"SMTP_ENABLE_STARTTLS": {
|
|
||||||
"description": "Enable STARTTLS? Default is 'auto'.",
|
|
||||||
"value": "auto",
|
|
||||||
"required": false
|
|
||||||
},
|
|
||||||
"SMTP_ENABLE_STARTTLS_AUTO": {
|
"SMTP_ENABLE_STARTTLS_AUTO": {
|
||||||
"description": "Enable STARTTLS if SMTP server supports it? Deprecated by SMTP_ENABLE_STARTTLS.",
|
"description": "Enable STARTTLS if SMTP server supports it? Default is true.",
|
||||||
"required": false
|
"required": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -100,5 +95,8 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed"
|
"postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed"
|
||||||
},
|
},
|
||||||
"addons": ["heroku-postgresql", "heroku-redis"]
|
"addons": [
|
||||||
|
"heroku-postgresql",
|
||||||
|
"heroku-redis"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountsIndex < Chewy::Index
|
class AccountsIndex < Chewy::Index
|
||||||
include DatetimeClampingConcern
|
settings index: { refresh_interval: '5m' }, analysis: {
|
||||||
|
|
||||||
settings index: index_preset(refresh_interval: '30s'), analysis: {
|
|
||||||
filter: {
|
|
||||||
english_stop: {
|
|
||||||
type: 'stop',
|
|
||||||
stopwords: '_english_',
|
|
||||||
},
|
|
||||||
|
|
||||||
english_stemmer: {
|
|
||||||
type: 'stemmer',
|
|
||||||
language: 'english',
|
|
||||||
},
|
|
||||||
|
|
||||||
english_possessive_stemmer: {
|
|
||||||
type: 'stemmer',
|
|
||||||
language: 'possessive_english',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
analyzer: {
|
analyzer: {
|
||||||
natural: {
|
content: {
|
||||||
tokenizer: 'standard',
|
tokenizer: 'whitespace',
|
||||||
filter: %w(
|
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
elision
|
|
||||||
english_possessive_stemmer
|
|
||||||
english_stop
|
|
||||||
english_stemmer
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
verbatim: {
|
|
||||||
tokenizer: 'standard',
|
|
||||||
filter: %w(lowercase asciifolding cjk_width),
|
filter: %w(lowercase asciifolding cjk_width),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -55,16 +23,21 @@ class AccountsIndex < Chewy::Index
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
index_scope ::Account.searchable.includes(:account_stat)
|
define_type ::Account.searchable.includes(:account_stat), delete_if: ->(account) { account.destroyed? || !account.searchable? } do
|
||||||
|
root date_detection: false do
|
||||||
|
field :id, type: 'long'
|
||||||
|
|
||||||
root date_detection: false do
|
field :display_name, type: 'text', analyzer: 'content' do
|
||||||
field(:id, type: 'long')
|
field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content'
|
||||||
field(:following_count, type: 'long')
|
end
|
||||||
field(:followers_count, type: 'long')
|
|
||||||
field(:properties, type: 'keyword', value: ->(account) { account.searchable_properties })
|
field :acct, type: 'text', analyzer: 'content', value: ->(account) { [account.username, account.domain].compact.join('@') } do
|
||||||
field(:last_status_at, type: 'date', value: ->(account) { clamp_date(account.last_status_at || account.created_at) })
|
field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content'
|
||||||
field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
|
end
|
||||||
field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
|
|
||||||
field(:text, type: 'text', analyzer: 'verbatim', value: ->(account) { account.searchable_text }) { field :stemmed, type: 'text', analyzer: 'natural' }
|
field :following_count, type: 'long', value: ->(account) { account.following.local.count }
|
||||||
|
field :followers_count, type: 'long', value: ->(account) { account.followers.local.count }
|
||||||
|
field :last_status_at, type: 'date', value: ->(account) { account.last_status_at || account.created_at }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module DatetimeClampingConcern
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
MIN_ISO8601_DATETIME = '0000-01-01T00:00:00Z'.to_datetime.freeze
|
|
||||||
MAX_ISO8601_DATETIME = '9999-12-31T23:59:59Z'.to_datetime.freeze
|
|
||||||
|
|
||||||
class_methods do
|
|
||||||
def clamp_date(datetime)
|
|
||||||
datetime.clamp(MIN_ISO8601_DATETIME, MAX_ISO8601_DATETIME)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,12 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class InstancesIndex < Chewy::Index
|
|
||||||
settings index: index_preset(refresh_interval: '30s')
|
|
||||||
|
|
||||||
index_scope ::Instance.searchable
|
|
||||||
|
|
||||||
root date_detection: false do
|
|
||||||
field :domain, type: 'text', index_prefixes: { min_chars: 1, max_chars: 5 }
|
|
||||||
field :accounts_count, type: 'long'
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,69 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class PublicStatusesIndex < Chewy::Index
|
|
||||||
include DatetimeClampingConcern
|
|
||||||
|
|
||||||
settings index: index_preset(refresh_interval: '30s', number_of_shards: 5), analysis: {
|
|
||||||
filter: {
|
|
||||||
english_stop: {
|
|
||||||
type: 'stop',
|
|
||||||
stopwords: '_english_',
|
|
||||||
},
|
|
||||||
|
|
||||||
english_stemmer: {
|
|
||||||
type: 'stemmer',
|
|
||||||
language: 'english',
|
|
||||||
},
|
|
||||||
|
|
||||||
english_possessive_stemmer: {
|
|
||||||
type: 'stemmer',
|
|
||||||
language: 'possessive_english',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
analyzer: {
|
|
||||||
verbatim: {
|
|
||||||
tokenizer: 'uax_url_email',
|
|
||||||
filter: %w(lowercase),
|
|
||||||
},
|
|
||||||
|
|
||||||
content: {
|
|
||||||
tokenizer: 'standard',
|
|
||||||
filter: %w(
|
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
elision
|
|
||||||
english_possessive_stemmer
|
|
||||||
english_stop
|
|
||||||
english_stemmer
|
|
||||||
),
|
|
||||||
},
|
|
||||||
|
|
||||||
hashtag: {
|
|
||||||
tokenizer: 'keyword',
|
|
||||||
filter: %w(
|
|
||||||
word_delimiter_graph
|
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
index_scope ::Status.unscoped
|
|
||||||
.kept
|
|
||||||
.indexable
|
|
||||||
.includes(:media_attachments, :preloadable_poll, :preview_cards, :tags)
|
|
||||||
|
|
||||||
root date_detection: false do
|
|
||||||
field(:id, type: 'long')
|
|
||||||
field(:account_id, type: 'long')
|
|
||||||
field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') }
|
|
||||||
field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) })
|
|
||||||
field(:language, type: 'keyword')
|
|
||||||
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
|
|
||||||
field(:created_at, type: 'date', value: ->(status) { clamp_date(status.created_at) })
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,67 +1,66 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class StatusesIndex < Chewy::Index
|
class StatusesIndex < Chewy::Index
|
||||||
include DatetimeClampingConcern
|
settings index: { refresh_interval: '15m' }, analysis: {
|
||||||
|
|
||||||
settings index: index_preset(refresh_interval: '30s', number_of_shards: 5), analysis: {
|
|
||||||
filter: {
|
filter: {
|
||||||
english_stop: {
|
english_stop: {
|
||||||
type: 'stop',
|
type: 'stop',
|
||||||
stopwords: '_english_',
|
stopwords: '_english_',
|
||||||
},
|
},
|
||||||
|
|
||||||
english_stemmer: {
|
english_stemmer: {
|
||||||
type: 'stemmer',
|
type: 'stemmer',
|
||||||
language: 'english',
|
language: 'english',
|
||||||
},
|
},
|
||||||
|
|
||||||
english_possessive_stemmer: {
|
english_possessive_stemmer: {
|
||||||
type: 'stemmer',
|
type: 'stemmer',
|
||||||
language: 'possessive_english',
|
language: 'possessive_english',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
analyzer: {
|
analyzer: {
|
||||||
verbatim: {
|
|
||||||
tokenizer: 'uax_url_email',
|
|
||||||
filter: %w(lowercase),
|
|
||||||
},
|
|
||||||
|
|
||||||
content: {
|
content: {
|
||||||
tokenizer: 'standard',
|
tokenizer: 'uax_url_email',
|
||||||
filter: %w(
|
filter: %w(
|
||||||
|
english_possessive_stemmer
|
||||||
lowercase
|
lowercase
|
||||||
asciifolding
|
asciifolding
|
||||||
cjk_width
|
cjk_width
|
||||||
elision
|
|
||||||
english_possessive_stemmer
|
|
||||||
english_stop
|
english_stop
|
||||||
english_stemmer
|
english_stemmer
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
hashtag: {
|
|
||||||
tokenizer: 'keyword',
|
|
||||||
filter: %w(
|
|
||||||
word_delimiter_graph
|
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }
|
define_type ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preloadable_poll) do
|
||||||
|
crutch :mentions do |collection|
|
||||||
|
data = ::Mention.where(status_id: collection.map(&:id)).where(account: Account.local, silent: false).pluck(:status_id, :account_id)
|
||||||
|
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
||||||
|
end
|
||||||
|
|
||||||
root date_detection: false do
|
crutch :favourites do |collection|
|
||||||
field(:id, type: 'long')
|
data = ::Favourite.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id)
|
||||||
field(:account_id, type: 'long')
|
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
||||||
field(:text, type: 'text', analyzer: 'verbatim', value: ->(status) { status.searchable_text }) { field(:stemmed, type: 'text', analyzer: 'content') }
|
end
|
||||||
field(:tags, type: 'text', analyzer: 'hashtag', value: ->(status) { status.tags.map(&:display_name) })
|
|
||||||
field(:searchable_by, type: 'long', value: ->(status) { status.searchable_by })
|
crutch :reblogs do |collection|
|
||||||
field(:language, type: 'keyword')
|
data = ::Status.where(reblog_of_id: collection.map(&:id)).where(account: Account.local).pluck(:reblog_of_id, :account_id)
|
||||||
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
|
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
||||||
field(:created_at, type: 'date', value: ->(status) { clamp_date(status.created_at) })
|
end
|
||||||
|
|
||||||
|
crutch :bookmarks do |collection|
|
||||||
|
data = ::Bookmark.where(status_id: collection.map(&:id)).where(account: Account.local).pluck(:status_id, :account_id)
|
||||||
|
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
||||||
|
end
|
||||||
|
|
||||||
|
root date_detection: false do
|
||||||
|
field :id, type: 'long'
|
||||||
|
field :account_id, type: 'long'
|
||||||
|
|
||||||
|
field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do
|
||||||
|
field :stemmed, type: 'text', analyzer: 'content'
|
||||||
|
end
|
||||||
|
|
||||||
|
field :searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,27 +1,16 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class TagsIndex < Chewy::Index
|
class TagsIndex < Chewy::Index
|
||||||
include DatetimeClampingConcern
|
settings index: { refresh_interval: '15m' }, analysis: {
|
||||||
|
|
||||||
settings index: index_preset(refresh_interval: '30s'), analysis: {
|
|
||||||
analyzer: {
|
analyzer: {
|
||||||
content: {
|
content: {
|
||||||
tokenizer: 'keyword',
|
tokenizer: 'keyword',
|
||||||
filter: %w(
|
filter: %w(lowercase asciifolding cjk_width),
|
||||||
word_delimiter_graph
|
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
edge_ngram: {
|
edge_ngram: {
|
||||||
tokenizer: 'edge_ngram',
|
tokenizer: 'edge_ngram',
|
||||||
filter: %w(
|
filter: %w(lowercase asciifolding cjk_width),
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -34,16 +23,15 @@ class TagsIndex < Chewy::Index
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
index_scope ::Tag.listable
|
define_type ::Tag.listable, delete_if: ->(tag) { tag.destroyed? || !tag.listable? } do
|
||||||
|
root date_detection: false do
|
||||||
|
field :name, type: 'text', analyzer: 'content' do
|
||||||
|
field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content'
|
||||||
|
end
|
||||||
|
|
||||||
crutch :time_period do
|
field :reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? }
|
||||||
7.days.ago.to_date..0.days.ago.to_date
|
field :usage, type: 'long', value: ->(tag) { tag.history.reduce(0) { |total, day| total + day[:accounts].to_i } }
|
||||||
end
|
field :last_status_at, type: 'date', value: ->(tag) { tag.last_status_at || tag.created_at }
|
||||||
|
end
|
||||||
root date_detection: false do
|
|
||||||
field(:name, type: 'text', analyzer: 'content', value: :display_name) { field(:edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content') }
|
|
||||||
field(:reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? })
|
|
||||||
field(:usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts })
|
|
||||||
field(:last_status_at, type: 'date', value: ->(tag) { clamp_date(tag.last_status_at || tag.created_at) })
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,67 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AboutController < ApplicationController
|
class AboutController < ApplicationController
|
||||||
include WebAppControllerConcern
|
include RegistrationSpamConcern
|
||||||
|
|
||||||
skip_before_action :require_functional!
|
layout 'public'
|
||||||
|
|
||||||
|
before_action :require_open_federation!, only: [:show, :more]
|
||||||
|
before_action :set_body_classes, only: :show
|
||||||
before_action :set_instance_presenter
|
before_action :set_instance_presenter
|
||||||
|
before_action :set_expires_in, only: [:more, :terms]
|
||||||
|
before_action :set_registration_form_time, only: :show
|
||||||
|
|
||||||
def show
|
skip_before_action :require_functional!, only: [:more, :terms]
|
||||||
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def more
|
||||||
|
flash.now[:notice] = I18n.t('about.instance_actor_flash') if params[:instance_actor]
|
||||||
|
|
||||||
|
toc_generator = TOCGenerator.new(@instance_presenter.site_extended_description)
|
||||||
|
|
||||||
|
@contents = toc_generator.html
|
||||||
|
@table_of_contents = toc_generator.toc
|
||||||
|
@blocks = DomainBlock.with_user_facing_limitations.by_severity if display_blocks?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def terms; end
|
||||||
|
|
||||||
|
helper_method :display_blocks?
|
||||||
|
helper_method :display_blocks_rationale?
|
||||||
|
helper_method :public_fetch_mode?
|
||||||
|
helper_method :new_user
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def require_open_federation!
|
||||||
|
not_found if whitelist_mode?
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_blocks?
|
||||||
|
Setting.show_domain_blocks == 'all' || (Setting.show_domain_blocks == 'users' && user_signed_in?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_blocks_rationale?
|
||||||
|
Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_user
|
||||||
|
User.new.tap do |user|
|
||||||
|
user.build_account
|
||||||
|
user.build_invite_request
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def set_instance_presenter
|
def set_instance_presenter
|
||||||
@instance_presenter = InstancePresenter.new
|
@instance_presenter = InstancePresenter.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@hide_navbar = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_expires_in
|
||||||
|
expires_in 0, public: true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
12
app/controllers/account_follow_controller.rb
Normal file
12
app/controllers/account_follow_controller.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccountFollowController < ApplicationController
|
||||||
|
include AccountControllerConcern
|
||||||
|
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
def create
|
||||||
|
FollowService.new.call(current_user.account, @account, with_rate_limit: true)
|
||||||
|
redirect_to account_path(@account)
|
||||||
|
end
|
||||||
|
end
|
12
app/controllers/account_unfollow_controller.rb
Normal file
12
app/controllers/account_unfollow_controller.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccountUnfollowController < ApplicationController
|
||||||
|
include AccountControllerConcern
|
||||||
|
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
def create
|
||||||
|
UnfollowService.new.call(current_user.account, @account)
|
||||||
|
redirect_to account_path(@account)
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,19 +7,35 @@ class AccountsController < ApplicationController
|
||||||
include AccountControllerConcern
|
include AccountControllerConcern
|
||||||
include SignatureAuthentication
|
include SignatureAuthentication
|
||||||
|
|
||||||
vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' }
|
before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
|
||||||
|
before_action :set_cache_headers
|
||||||
before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
|
before_action :set_body_classes
|
||||||
|
|
||||||
skip_around_action :set_locale, if: -> { [:json, :rss].include?(request.format&.to_sym) }
|
skip_around_action :set_locale, if: -> { [:json, :rss].include?(request.format&.to_sym) }
|
||||||
skip_before_action :require_functional!, unless: :limited_federation_mode?
|
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.hour) unless user_signed_in?
|
expires_in 0, public: true unless user_signed_in?
|
||||||
|
|
||||||
@rss_url = rss_url
|
@pinned_statuses = []
|
||||||
|
@endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
|
||||||
|
@featured_hashtags = @account.featured_tags.order(statuses_count: :desc)
|
||||||
|
|
||||||
|
if current_account && @account.blocking?(current_account)
|
||||||
|
@statuses = []
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
|
||||||
|
@statuses = cached_filtered_status_page
|
||||||
|
@rss_url = rss_url
|
||||||
|
|
||||||
|
unless @statuses.empty?
|
||||||
|
@older_url = older_url if @statuses.last.id > filtered_statuses.last.id
|
||||||
|
@newer_url = newer_url if @statuses.first.id < filtered_statuses.first.id
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
format.rss do
|
format.rss do
|
||||||
|
@ -28,6 +44,7 @@ class AccountsController < ApplicationController
|
||||||
limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE
|
limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE
|
||||||
@statuses = filtered_statuses.without_reblogs.limit(limit)
|
@statuses = filtered_statuses.without_reblogs.limit(limit)
|
||||||
@statuses = cache_collection(@statuses, Status)
|
@statuses = cache_collection(@statuses, Status)
|
||||||
|
render xml: RSS::AccountSerializer.render(@account, @statuses, params[:tag])
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
|
@ -39,6 +56,14 @@ class AccountsController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@body_classes = 'with-modals'
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_pinned_statuses?
|
||||||
|
[replies_requested?, media_requested?, tag_requested?, params[:max_id].present?, params[:min_id].present?].none?
|
||||||
|
end
|
||||||
|
|
||||||
def filtered_statuses
|
def filtered_statuses
|
||||||
default_statuses.tap do |statuses|
|
default_statuses.tap do |statuses|
|
||||||
statuses.merge!(hashtag_scope) if tag_requested?
|
statuses.merge!(hashtag_scope) if tag_requested?
|
||||||
|
@ -52,7 +77,11 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def only_media_scope
|
def only_media_scope
|
||||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id)
|
Status.where(id: account_media_status_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_media_status_ids
|
||||||
|
@account.media_attachments.attached.reorder(nil).select(:status_id).group(:status_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def no_replies_scope
|
def no_replies_scope
|
||||||
|
@ -85,16 +114,36 @@ class AccountsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def older_url
|
||||||
|
pagination_url(max_id: @statuses.last.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def newer_url
|
||||||
|
pagination_url(min_id: @statuses.first.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_url(max_id: nil, min_id: nil)
|
||||||
|
if tag_requested?
|
||||||
|
short_account_tag_url(@account, params[:tag], max_id: max_id, min_id: min_id)
|
||||||
|
elsif media_requested?
|
||||||
|
short_account_media_url(@account, max_id: max_id, min_id: min_id)
|
||||||
|
elsif replies_requested?
|
||||||
|
short_account_with_replies_url(@account, max_id: max_id, min_id: min_id)
|
||||||
|
else
|
||||||
|
short_account_url(@account, max_id: max_id, min_id: min_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def media_requested?
|
def media_requested?
|
||||||
request.path.split('.').first.end_with?('/media') && !tag_requested?
|
request.path.split('.').first.ends_with?('/media') && !tag_requested?
|
||||||
end
|
end
|
||||||
|
|
||||||
def replies_requested?
|
def replies_requested?
|
||||||
request.path.split('.').first.end_with?('/with_replies') && !tag_requested?
|
request.path.split('.').first.ends_with?('/with_replies') && !tag_requested?
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_requested?
|
def tag_requested?
|
||||||
request.path.split('.').first.end_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
|
request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cached_filtered_status_page
|
def cached_filtered_status_page
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
|
|
||||||
class ActivityPub::BaseController < Api::BaseController
|
class ActivityPub::BaseController < Api::BaseController
|
||||||
skip_before_action :require_authenticated_user!
|
skip_before_action :require_authenticated_user!
|
||||||
skip_before_action :require_not_suspended!
|
|
||||||
skip_around_action :set_locale
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.headers['Vary'] = 'Signature' if authorized_fetch_mode?
|
||||||
|
end
|
||||||
|
|
||||||
def skip_temporary_suspension_response?
|
def skip_temporary_suspension_response?
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ class ActivityPub::ClaimsController < ActivityPub::BaseController
|
||||||
|
|
||||||
skip_before_action :authenticate_user!
|
skip_before_action :authenticate_user!
|
||||||
|
|
||||||
before_action :require_account_signature!
|
before_action :require_signature!
|
||||||
before_action :set_claim_result
|
before_action :set_claim_result
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
|
|
@ -4,12 +4,11 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
||||||
include SignatureVerification
|
include SignatureVerification
|
||||||
include AccountOwnedConcern
|
include AccountOwnedConcern
|
||||||
|
|
||||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
before_action :require_signature!, if: :authorized_fetch_mode?
|
||||||
|
|
||||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
|
||||||
before_action :set_items
|
before_action :set_items
|
||||||
before_action :set_size
|
before_action :set_size
|
||||||
before_action :set_type
|
before_action :set_type
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in 3.minutes, public: public_fetch_mode?
|
expires_in 3.minutes, public: public_fetch_mode?
|
||||||
|
@ -22,7 +21,6 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
||||||
case params[:id]
|
case params[:id]
|
||||||
when 'featured'
|
when 'featured'
|
||||||
@items = for_signed_account { cache_collection(@account.pinned_statuses, Status) }
|
@items = for_signed_account { cache_collection(@account.pinned_statuses, Status) }
|
||||||
@items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) }
|
|
||||||
when 'tags'
|
when 'tags'
|
||||||
@items = for_signed_account { @account.featured_tags }
|
@items = for_signed_account { @account.featured_tags }
|
||||||
when 'devices'
|
when 'devices'
|
||||||
|
|
|
@ -4,10 +4,9 @@ class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseContro
|
||||||
include SignatureVerification
|
include SignatureVerification
|
||||||
include AccountOwnedConcern
|
include AccountOwnedConcern
|
||||||
|
|
||||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
before_action :require_signature!
|
||||||
|
|
||||||
before_action :require_account_signature!
|
|
||||||
before_action :set_items
|
before_action :set_items
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in 0, public: false
|
expires_in 0, public: false
|
||||||
|
|
|
@ -6,7 +6,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
|
||||||
include AccountOwnedConcern
|
include AccountOwnedConcern
|
||||||
|
|
||||||
before_action :skip_unknown_actor_activity
|
before_action :skip_unknown_actor_activity
|
||||||
before_action :require_actor_signature!
|
before_action :require_signature!
|
||||||
skip_before_action :authenticate_user!
|
skip_before_action :authenticate_user!
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -49,17 +49,17 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def upgrade_account
|
def upgrade_account
|
||||||
if signed_request_account&.ostatus?
|
if signed_request_account.ostatus?
|
||||||
signed_request_account.update(last_webfingered_at: nil)
|
signed_request_account.update(last_webfingered_at: nil)
|
||||||
ResolveAccountWorker.perform_async(signed_request_account.acct)
|
ResolveAccountWorker.perform_async(signed_request_account.acct)
|
||||||
end
|
end
|
||||||
|
|
||||||
DeliveryFailureTracker.reset!(signed_request_actor.inbox_url)
|
DeliveryFailureTracker.reset!(signed_request_account.inbox_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_collection_synchronization
|
def process_collection_synchronization
|
||||||
raw_params = request.headers['Collection-Synchronization']
|
raw_params = request.headers['Collection-Synchronization']
|
||||||
return if raw_params.blank? || ENV['DISABLE_FOLLOWERS_SYNCHRONIZATION'] == 'true' || signed_request_account.nil?
|
return if raw_params.blank? || ENV['DISABLE_FOLLOWERS_SYNCHRONIZATION'] == 'true'
|
||||||
|
|
||||||
# Re-using the syntax for signature parameters
|
# Re-using the syntax for signature parameters
|
||||||
tree = SignatureParamsParser.new.parse(raw_params)
|
tree = SignatureParamsParser.new.parse(raw_params)
|
||||||
|
@ -71,6 +71,6 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_payload
|
def process_payload
|
||||||
ActivityPub::ProcessingWorker.perform_async(signed_request_actor.id, body, @account&.id, signed_request_actor.class.name)
|
ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body, @account&.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,18 +6,12 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||||
include SignatureVerification
|
include SignatureVerification
|
||||||
include AccountOwnedConcern
|
include AccountOwnedConcern
|
||||||
|
|
||||||
vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? }
|
before_action :require_signature!, if: :authorized_fetch_mode?
|
||||||
|
|
||||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
|
||||||
before_action :set_statuses
|
before_action :set_statuses
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
if page_requested?
|
expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode? && !(signed_request_account.present? && page_requested?))
|
||||||
expires_in(1.minute, public: public_fetch_mode? && signed_request_account.nil?)
|
|
||||||
else
|
|
||||||
expires_in(3.minutes, public: public_fetch_mode?)
|
|
||||||
end
|
|
||||||
|
|
||||||
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,7 +20,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||||
def outbox_presenter
|
def outbox_presenter
|
||||||
if page_requested?
|
if page_requested?
|
||||||
ActivityPub::CollectionPresenter.new(
|
ActivityPub::CollectionPresenter.new(
|
||||||
id: outbox_url(**page_params),
|
id: outbox_url(page_params),
|
||||||
type: :ordered,
|
type: :ordered,
|
||||||
part_of: outbox_url,
|
part_of: outbox_url,
|
||||||
prev: prev_page,
|
prev: prev_page,
|
||||||
|
@ -64,7 +58,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||||
return unless page_requested?
|
return unless page_requested?
|
||||||
|
|
||||||
@statuses = cache_collection_paginated_by_id(
|
@statuses = cache_collection_paginated_by_id(
|
||||||
AccountStatusesFilter.new(@account, signed_request_account).results,
|
@account.statuses.permitted_for(@account, signed_request_account),
|
||||||
Status,
|
Status,
|
||||||
LIMIT,
|
LIMIT,
|
||||||
params_slice(:max_id, :min_id, :since_id)
|
params_slice(:max_id, :min_id, :since_id)
|
||||||
|
|
|
@ -7,10 +7,9 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
||||||
|
|
||||||
DESCENDANTS_LIMIT = 60
|
DESCENDANTS_LIMIT = 60
|
||||||
|
|
||||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
before_action :require_signature!, if: :authorized_fetch_mode?
|
||||||
|
|
||||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
|
||||||
before_action :set_status
|
before_action :set_status
|
||||||
|
before_action :set_cache_headers
|
||||||
before_action :set_replies
|
before_action :set_replies
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -64,29 +63,15 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_page
|
def next_page
|
||||||
if only_other_accounts?
|
only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
|
||||||
# Only consider remote accounts
|
|
||||||
return nil if @replies.size < DESCENDANTS_LIMIT
|
|
||||||
|
|
||||||
account_status_replies_url(
|
account_status_replies_url(
|
||||||
@account,
|
@account,
|
||||||
@status,
|
@status,
|
||||||
page: true,
|
page: true,
|
||||||
min_id: @replies&.last&.id,
|
min_id: only_other_accounts && !only_other_accounts? ? nil : @replies&.last&.id,
|
||||||
only_other_accounts: true
|
only_other_accounts: only_other_accounts
|
||||||
)
|
)
|
||||||
else
|
|
||||||
# For now, we're serving only self-replies, but next page might be other accounts
|
|
||||||
next_only_other_accounts = @replies&.last&.account_id != @account.id || @replies.size < DESCENDANTS_LIMIT
|
|
||||||
|
|
||||||
account_status_replies_url(
|
|
||||||
@account,
|
|
||||||
@status,
|
|
||||||
page: true,
|
|
||||||
min_id: next_only_other_accounts ? nil : @replies&.last&.id,
|
|
||||||
only_other_accounts: next_only_other_accounts
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def page_params
|
def page_params
|
||||||
|
|
|
@ -5,15 +5,11 @@ module Admin
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
|
||||||
def new
|
def new
|
||||||
authorize @account, :show?
|
|
||||||
|
|
||||||
@account_action = Admin::AccountAction.new(type: params[:type], report_id: params[:report_id], send_email_notification: true, include_statuses: true)
|
@account_action = Admin::AccountAction.new(type: params[:type], report_id: params[:report_id], send_email_notification: true, include_statuses: true)
|
||||||
@warning_presets = AccountWarningPreset.all
|
@warning_presets = AccountWarningPreset.all
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @account, :show?
|
|
||||||
|
|
||||||
account_action = Admin::AccountAction.new(resource_params)
|
account_action = Admin::AccountAction.new(resource_params)
|
||||||
account_action.target_account = @account
|
account_action.target_account = @account
|
||||||
account_action.current_account = current_account
|
account_action.current_account = current_account
|
||||||
|
@ -21,7 +17,7 @@ module Admin
|
||||||
account_action.save!
|
account_action.save!
|
||||||
|
|
||||||
if account_action.with_report?
|
if account_action.with_report?
|
||||||
redirect_to admin_reports_path, notice: I18n.t('admin.reports.processed_msg', id: resource_params[:report_id])
|
redirect_to admin_reports_path
|
||||||
else
|
else
|
||||||
redirect_to admin_account_path(@account.id)
|
redirect_to admin_account_path(@account.id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ module Admin
|
||||||
else
|
else
|
||||||
@account = @account_moderation_note.target_account
|
@account = @account_moderation_note.target_account
|
||||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
@moderation_notes = @account.targeted_moderation_notes.latest
|
||||||
@warnings = @account.strikes.custom.latest
|
@warnings = @account.targeted_account_warnings.latest.custom
|
||||||
|
|
||||||
render template: 'admin/accounts/show'
|
render template: 'admin/accounts/show'
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,30 +2,13 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class AccountsController < BaseController
|
class AccountsController < BaseController
|
||||||
before_action :set_account, except: [:index, :batch]
|
before_action :set_account, except: [:index]
|
||||||
before_action :require_remote_account!, only: [:redownload]
|
before_action :require_remote_account!, only: [:redownload]
|
||||||
before_action :require_local_account!, only: [:enable, :memorialize, :approve, :reject]
|
before_action :require_local_account!, only: [:enable, :memorialize, :approve, :reject]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :account, :index?
|
authorize :account, :index?
|
||||||
|
|
||||||
@accounts = filtered_accounts.page(params[:page])
|
@accounts = filtered_accounts.page(params[:page])
|
||||||
@form = Form::AccountBatch.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch
|
|
||||||
authorize :account, :index?
|
|
||||||
|
|
||||||
@form = Form::AccountBatch.new(form_account_batch_params)
|
|
||||||
@form.current_account = current_account
|
|
||||||
@form.action = action_from_button
|
|
||||||
@form.select_all_matching = params[:select_all_matching]
|
|
||||||
@form.query = filtered_accounts
|
|
||||||
@form.save
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
flash[:alert] = I18n.t('admin.accounts.no_account_selected')
|
|
||||||
ensure
|
|
||||||
redirect_to admin_accounts_path(filter_params)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@ -34,7 +17,7 @@ module Admin
|
||||||
@deletion_request = @account.deletion_request
|
@deletion_request = @account.deletion_request
|
||||||
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
|
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
|
||||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
@moderation_notes = @account.targeted_moderation_notes.latest
|
||||||
@warnings = @account.strikes.includes(:target_account, :account, :appeal).latest
|
@warnings = @account.targeted_account_warnings.latest.custom
|
||||||
@domain_block = DomainBlock.rule_for(@account.domain)
|
@domain_block = DomainBlock.rule_for(@account.domain)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,15 +38,13 @@ module Admin
|
||||||
def approve
|
def approve
|
||||||
authorize @account.user, :approve?
|
authorize @account.user, :approve?
|
||||||
@account.user.approve!
|
@account.user.approve!
|
||||||
log_action :approve, @account.user
|
redirect_to admin_pending_accounts_path, notice: I18n.t('admin.accounts.approved_msg', username: @account.acct)
|
||||||
redirect_to admin_accounts_path(status: 'pending'), notice: I18n.t('admin.accounts.approved_msg', username: @account.acct)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def reject
|
def reject
|
||||||
authorize @account.user, :reject?
|
authorize @account.user, :reject?
|
||||||
DeleteAccountService.new.call(@account, reserve_email: false, reserve_username: false)
|
DeleteAccountService.new.call(@account, reserve_email: false, reserve_username: false)
|
||||||
log_action :reject, @account.user
|
redirect_to admin_pending_accounts_path, notice: I18n.t('admin.accounts.rejected_msg', username: @account.acct)
|
||||||
redirect_to admin_accounts_path(status: 'pending'), notice: I18n.t('admin.accounts.rejected_msg', username: @account.acct)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -125,16 +106,6 @@ module Admin
|
||||||
redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.removed_header_msg', username: @account.acct)
|
redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.removed_header_msg', username: @account.acct)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unblock_email
|
|
||||||
authorize @account, :unblock_email?
|
|
||||||
|
|
||||||
CanonicalEmailBlock.where(reference_account: @account).delete_all
|
|
||||||
|
|
||||||
log_action :unblock_email, @account
|
|
||||||
|
|
||||||
redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.unblocked_email_msg', username: @account.acct)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_account
|
def set_account
|
||||||
|
@ -150,25 +121,11 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def filtered_accounts
|
def filtered_accounts
|
||||||
AccountFilter.new(filter_params.with_defaults(order: 'recent')).results
|
AccountFilter.new(filter_params).results
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_params
|
def filter_params
|
||||||
params.slice(:page, *AccountFilter::KEYS).permit(:page, *AccountFilter::KEYS)
|
params.slice(*AccountFilter::KEYS).permit(*AccountFilter::KEYS)
|
||||||
end
|
|
||||||
|
|
||||||
def form_account_batch_params
|
|
||||||
params.require(:form_account_batch).permit(:action, account_ids: [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def action_from_button
|
|
||||||
if params[:suspend]
|
|
||||||
'suspend'
|
|
||||||
elsif params[:approve]
|
|
||||||
'approve'
|
|
||||||
elsif params[:reject]
|
|
||||||
'reject'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,10 +4,7 @@ module Admin
|
||||||
class ActionLogsController < BaseController
|
class ActionLogsController < BaseController
|
||||||
before_action :set_action_logs
|
before_action :set_action_logs
|
||||||
|
|
||||||
def index
|
def index; end
|
||||||
authorize :audit_log, :index?
|
|
||||||
@auditable_accounts = Account.where(id: Admin::ActionLog.reorder(nil).select('distinct account_id')).select(:id, :username)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,6 @@ class Admin::AnnouncementsController < Admin::BaseController
|
||||||
@announcement = Announcement.new
|
@announcement = Announcement.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
|
||||||
authorize :announcement, :update?
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize :announcement, :create?
|
authorize :announcement, :create?
|
||||||
|
|
||||||
|
@ -32,6 +28,10 @@ class Admin::AnnouncementsController < Admin::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
authorize :announcement, :update?
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize :announcement, :update?
|
authorize :announcement, :update?
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,8 @@ module Admin
|
||||||
|
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
|
before_action :require_staff!
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
before_action :set_cache_headers
|
|
||||||
|
|
||||||
after_action :verify_authorized
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -18,10 +16,6 @@ module Admin
|
||||||
@body_classes = 'admin'
|
@body_classes = 'admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
|
||||||
response.cache_control.replace(private: true, no_store: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_user
|
def set_user
|
||||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,7 +17,7 @@ module Admin
|
||||||
|
|
||||||
@user.resend_confirmation_instructions
|
@user.resend_confirmation_instructions
|
||||||
|
|
||||||
log_action :resend, @user
|
log_action :confirm, @user
|
||||||
|
|
||||||
flash[:notice] = I18n.t('admin.accounts.resend_confirmation.success')
|
flash[:notice] = I18n.t('admin.accounts.resend_confirmation.success')
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
|
|
|
@ -29,12 +29,10 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch
|
def batch
|
||||||
authorize :custom_emoji, :index?
|
|
||||||
|
|
||||||
@form = Form::CustomEmojiBatch.new(form_custom_emoji_batch_params.merge(current_account: current_account, action: action_from_button))
|
@form = Form::CustomEmojiBatch.new(form_custom_emoji_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
@form.save
|
@form.save
|
||||||
rescue ActionController::ParameterMissing
|
rescue ActionController::ParameterMissing
|
||||||
flash[:alert] = I18n.t('admin.custom_emojis.no_emoji_selected')
|
flash[:alert] = I18n.t('admin.accounts.no_account_selected')
|
||||||
rescue Mastodon::NotPermittedError
|
rescue Mastodon::NotPermittedError
|
||||||
flash[:alert] = I18n.t('admin.custom_emojis.not_permitted')
|
flash[:alert] = I18n.t('admin.custom_emojis.not_permitted')
|
||||||
ensure
|
ensure
|
||||||
|
|
|
@ -1,18 +1,57 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
require 'sidekiq/api'
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class DashboardController < BaseController
|
class DashboardController < BaseController
|
||||||
include Redisable
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :dashboard, :index?
|
@users_count = User.count
|
||||||
|
|
||||||
@system_checks = Admin::SystemCheck.perform(current_user)
|
|
||||||
@time_period = (29.days.ago.to_date...Time.now.utc.to_date)
|
|
||||||
@pending_users_count = User.pending.count
|
@pending_users_count = User.pending.count
|
||||||
@pending_reports_count = Report.unresolved.count
|
@registrations_week = Redis.current.get("activity:accounts:local:#{current_week}") || 0
|
||||||
|
@logins_week = Redis.current.pfcount("activity:logins:#{current_week}")
|
||||||
|
@interactions_week = Redis.current.get("activity:interactions:#{current_week}") || 0
|
||||||
|
@relay_enabled = Relay.enabled.exists?
|
||||||
|
@single_user_mode = Rails.configuration.x.single_user_mode
|
||||||
|
@registrations_enabled = Setting.registrations_mode != 'none'
|
||||||
|
@deletions_enabled = Setting.open_deletion
|
||||||
|
@invites_enabled = Setting.min_invite_role == 'user'
|
||||||
|
@search_enabled = Chewy.enabled?
|
||||||
|
@version = Mastodon::Version.to_s
|
||||||
|
@database_version = ActiveRecord::Base.connection.execute('SELECT VERSION()').first['version'].match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1]
|
||||||
|
@redis_version = redis_info['redis_version']
|
||||||
|
@reports_count = Report.unresolved.count
|
||||||
|
@queue_backlog = Sidekiq::Stats.new.enqueued
|
||||||
|
@recent_users = User.confirmed.recent.includes(:account).limit(8)
|
||||||
|
@database_size = ActiveRecord::Base.connection.execute('SELECT pg_database_size(current_database())').first['pg_database_size']
|
||||||
|
@redis_size = redis_info['used_memory']
|
||||||
|
@ldap_enabled = ENV['LDAP_ENABLED'] == 'true'
|
||||||
|
@cas_enabled = ENV['CAS_ENABLED'] == 'true'
|
||||||
|
@saml_enabled = ENV['SAML_ENABLED'] == 'true'
|
||||||
|
@pam_enabled = ENV['PAM_ENABLED'] == 'true'
|
||||||
|
@hidden_service = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
|
||||||
|
@trending_hashtags = TrendingTags.get(10, filtered: false)
|
||||||
@pending_tags_count = Tag.pending_review.count
|
@pending_tags_count = Tag.pending_review.count
|
||||||
@pending_appeals_count = Appeal.pending.count
|
@authorized_fetch = authorized_fetch_mode?
|
||||||
|
@whitelist_enabled = whitelist_mode?
|
||||||
|
@profile_directory = Setting.profile_directory
|
||||||
|
@timeline_preview = Setting.timeline_preview
|
||||||
|
@spam_check_enabled = Setting.spam_check_enabled
|
||||||
|
@trends_enabled = Setting.trends
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_week
|
||||||
|
@current_week ||= Time.now.utc.to_date.cweek
|
||||||
|
end
|
||||||
|
|
||||||
|
def redis_info
|
||||||
|
@redis_info ||= begin
|
||||||
|
if Redis.current.is_a?(Redis::Namespace)
|
||||||
|
Redis.current.redis.info
|
||||||
|
else
|
||||||
|
Redis.current.info
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Admin::Disputes::AppealsController < Admin::BaseController
|
|
||||||
before_action :set_appeal, except: :index
|
|
||||||
|
|
||||||
def index
|
|
||||||
authorize :appeal, :index?
|
|
||||||
|
|
||||||
@appeals = filtered_appeals.page(params[:page])
|
|
||||||
end
|
|
||||||
|
|
||||||
def approve
|
|
||||||
authorize @appeal, :approve?
|
|
||||||
log_action :approve, @appeal
|
|
||||||
ApproveAppealService.new.call(@appeal, current_account)
|
|
||||||
redirect_to disputes_strike_path(@appeal.strike)
|
|
||||||
end
|
|
||||||
|
|
||||||
def reject
|
|
||||||
authorize @appeal, :approve?
|
|
||||||
log_action :reject, @appeal
|
|
||||||
@appeal.reject!(current_account)
|
|
||||||
UserMailer.appeal_rejected(@appeal.account.user, @appeal)
|
|
||||||
redirect_to disputes_strike_path(@appeal.strike)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def filtered_appeals
|
|
||||||
Admin::AppealFilter.new(filter_params.with_defaults(status: 'pending')).results.includes(strike: :account)
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter_params
|
|
||||||
params.slice(:page, *Admin::AppealFilter::KEYS).permit(:page, *Admin::AppealFilter::KEYS)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_appeal
|
|
||||||
@appeal = Appeal.find(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -25,8 +25,6 @@ class Admin::DomainAllowsController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
authorize @domain_allow, :destroy?
|
authorize @domain_allow, :destroy?
|
||||||
UnallowDomainService.new.call(@domain_allow)
|
UnallowDomainService.new.call(@domain_allow)
|
||||||
log_action :destroy, @domain_allow
|
|
||||||
|
|
||||||
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
|
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,7 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class DomainBlocksController < BaseController
|
class DomainBlocksController < BaseController
|
||||||
before_action :set_domain_block, only: [:destroy, :edit, :update]
|
before_action :set_domain_block, only: [:show, :destroy, :edit, :update]
|
||||||
|
|
||||||
def batch
|
|
||||||
authorize :domain_block, :create?
|
|
||||||
@form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
|
||||||
@form.save
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
flash[:alert] = I18n.t('admin.domain_blocks.no_domain_block_selected')
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
flash[:alert] = I18n.t('admin.domain_blocks.not_permitted')
|
|
||||||
else
|
|
||||||
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
authorize :domain_block, :create?
|
authorize :domain_block, :create?
|
||||||
|
@ -31,42 +19,36 @@ module Admin
|
||||||
@domain_block = DomainBlock.new(resource_params)
|
@domain_block = DomainBlock.new(resource_params)
|
||||||
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
|
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
|
||||||
|
|
||||||
# Disallow accidentally downgrading a domain block
|
|
||||||
if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block)
|
if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block)
|
||||||
@domain_block.save
|
@domain_block.save
|
||||||
flash.now[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe
|
flash.now[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe # rubocop:disable Rails/OutputSafety
|
||||||
@domain_block.errors.delete(:domain)
|
@domain_block.errors[:domain].clear
|
||||||
return render :new
|
|
||||||
end
|
|
||||||
|
|
||||||
# Allow transparently upgrading a domain block
|
|
||||||
if existing_domain_block.present? && existing_domain_block.domain == TagManager.instance.normalize_domain(@domain_block.domain.strip)
|
|
||||||
@domain_block = existing_domain_block
|
|
||||||
@domain_block.assign_attributes(resource_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Require explicit confirmation when suspending
|
|
||||||
return render :confirm_suspension if requires_confirmation?
|
|
||||||
|
|
||||||
if @domain_block.save
|
|
||||||
DomainBlockWorker.perform_async(@domain_block.id)
|
|
||||||
log_action :create, @domain_block
|
|
||||||
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
|
||||||
else
|
|
||||||
render :new
|
render :new
|
||||||
|
else
|
||||||
|
if existing_domain_block.present?
|
||||||
|
@domain_block = existing_domain_block
|
||||||
|
@domain_block.update(resource_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
if @domain_block.save
|
||||||
|
DomainBlockWorker.perform_async(@domain_block.id)
|
||||||
|
log_action :create, @domain_block
|
||||||
|
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize :domain_block, :update?
|
authorize :domain_block, :update?
|
||||||
|
|
||||||
@domain_block.assign_attributes(update_params)
|
@domain_block.update(update_params)
|
||||||
|
|
||||||
# Require explicit confirmation when suspending
|
severity_changed = @domain_block.severity_changed?
|
||||||
return render :confirm_suspension if requires_confirmation?
|
|
||||||
|
|
||||||
if @domain_block.save
|
if @domain_block.save
|
||||||
DomainBlockWorker.perform_async(@domain_block.id, @domain_block.severity_previously_changed?)
|
DomainBlockWorker.perform_async(@domain_block.id, severity_changed)
|
||||||
log_action :update, @domain_block
|
log_action :update, @domain_block
|
||||||
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
||||||
else
|
else
|
||||||
|
@ -74,6 +56,10 @@ module Admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
authorize @domain_block, :show?
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @domain_block, :destroy?
|
authorize @domain_block, :destroy?
|
||||||
UnblockDomainService.new.call(@domain_block)
|
UnblockDomainService.new.call(@domain_block)
|
||||||
|
@ -94,17 +80,5 @@ module Admin
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
|
||||||
end
|
end
|
||||||
|
|
||||||
def form_domain_block_batch_params
|
|
||||||
params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate])
|
|
||||||
end
|
|
||||||
|
|
||||||
def action_from_button
|
|
||||||
'save' if params[:save]
|
|
||||||
end
|
|
||||||
|
|
||||||
def requires_confirmation?
|
|
||||||
@domain_block.valid? && (@domain_block.new_record? || @domain_block.severity_changed?) && @domain_block.severity.to_s == 'suspend' && !params[:confirm]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,24 +2,11 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class EmailDomainBlocksController < BaseController
|
class EmailDomainBlocksController < BaseController
|
||||||
|
before_action :set_email_domain_block, only: [:show, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :email_domain_block, :index?
|
authorize :email_domain_block, :index?
|
||||||
|
|
||||||
@email_domain_blocks = EmailDomainBlock.where(parent_id: nil).includes(:children).order(id: :desc).page(params[:page])
|
@email_domain_blocks = EmailDomainBlock.where(parent_id: nil).includes(:children).order(id: :desc).page(params[:page])
|
||||||
@form = Form::EmailDomainBlockBatch.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def batch
|
|
||||||
authorize :email_domain_block, :index?
|
|
||||||
|
|
||||||
@form = Form::EmailDomainBlockBatch.new(form_email_domain_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
|
||||||
@form.save
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
flash[:alert] = I18n.t('admin.email_domain_blocks.no_email_domain_block_selected')
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
flash[:alert] = I18n.t('admin.email_domain_blocks.not_permitted')
|
|
||||||
ensure
|
|
||||||
redirect_to admin_email_domain_blocks_path
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
@ -32,52 +19,51 @@ module Admin
|
||||||
|
|
||||||
@email_domain_block = EmailDomainBlock.new(resource_params)
|
@email_domain_block = EmailDomainBlock.new(resource_params)
|
||||||
|
|
||||||
if action_from_button == 'save'
|
if @email_domain_block.save
|
||||||
EmailDomainBlock.transaction do
|
log_action :create, @email_domain_block
|
||||||
@email_domain_block.save!
|
|
||||||
log_action :create, @email_domain_block
|
|
||||||
|
|
||||||
(@email_domain_block.other_domains || []).uniq.each do |domain|
|
if @email_domain_block.with_dns_records?
|
||||||
next if EmailDomainBlock.where(domain: domain).exists?
|
hostnames = []
|
||||||
|
ips = []
|
||||||
|
|
||||||
other_email_domain_block = EmailDomainBlock.create!(domain: domain, parent: @email_domain_block)
|
Resolv::DNS.open do |dns|
|
||||||
log_action :create, other_email_domain_block
|
dns.timeouts = 5
|
||||||
|
|
||||||
|
hostnames = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a.map { |e| e.exchange.to_s }
|
||||||
|
|
||||||
|
([@email_domain_block.domain] + hostnames).uniq.each do |hostname|
|
||||||
|
ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::A).to_a.map { |e| e.address.to_s })
|
||||||
|
ips.concat(dns.getresources(hostname, Resolv::DNS::Resource::IN::AAAA).to_a.map { |e| e.address.to_s })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
(hostnames + ips).each do |hostname|
|
||||||
|
another_email_domain_block = EmailDomainBlock.new(domain: hostname, parent: @email_domain_block)
|
||||||
|
log_action :create, another_email_domain_block if another_email_domain_block.save
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg')
|
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg')
|
||||||
else
|
else
|
||||||
set_resolved_records
|
|
||||||
render :new
|
render :new
|
||||||
end
|
end
|
||||||
rescue ActiveRecord::RecordInvalid
|
end
|
||||||
set_resolved_records
|
|
||||||
render :new
|
def destroy
|
||||||
|
authorize @email_domain_block, :destroy?
|
||||||
|
@email_domain_block.destroy!
|
||||||
|
log_action :destroy, @email_domain_block
|
||||||
|
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.destroyed_msg')
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_resolved_records
|
def set_email_domain_block
|
||||||
Resolv::DNS.open do |dns|
|
@email_domain_block = EmailDomainBlock.find(params[:id])
|
||||||
dns.timeouts = 5
|
|
||||||
@resolved_records = dns.getresources(@email_domain_block.domain, Resolv::DNS::Resource::IN::MX).to_a
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:email_domain_block).permit(:domain, other_domains: [])
|
params.require(:email_domain_block).permit(:domain, :with_dns_records)
|
||||||
end
|
|
||||||
|
|
||||||
def form_email_domain_block_batch_params
|
|
||||||
params.require(:form_email_domain_block_batch).permit(email_domain_block_ids: [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def action_from_button
|
|
||||||
if params[:delete]
|
|
||||||
'delete'
|
|
||||||
elsif params[:save]
|
|
||||||
'save'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'csv'
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class ExportDomainAllowsController < BaseController
|
|
||||||
include AdminExportControllerConcern
|
|
||||||
|
|
||||||
before_action :set_dummy_import!, only: [:new]
|
|
||||||
|
|
||||||
def new
|
|
||||||
authorize :domain_allow, :create?
|
|
||||||
end
|
|
||||||
|
|
||||||
def export
|
|
||||||
authorize :instance, :index?
|
|
||||||
send_export_file
|
|
||||||
end
|
|
||||||
|
|
||||||
def import
|
|
||||||
authorize :domain_allow, :create?
|
|
||||||
begin
|
|
||||||
@import = Admin::Import.new(import_params)
|
|
||||||
return render :new unless @import.validate
|
|
||||||
|
|
||||||
@import.csv_rows.each do |row|
|
|
||||||
domain = row['#domain'].strip
|
|
||||||
next if DomainAllow.allowed?(domain)
|
|
||||||
|
|
||||||
domain_allow = DomainAllow.new(domain: domain)
|
|
||||||
log_action :create, domain_allow if domain_allow.save
|
|
||||||
end
|
|
||||||
flash[:notice] = I18n.t('admin.domain_allows.created_msg')
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
flash[:error] = I18n.t('admin.export_domain_allows.no_file')
|
|
||||||
end
|
|
||||||
redirect_to admin_instances_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def export_filename
|
|
||||||
'domain_allows.csv'
|
|
||||||
end
|
|
||||||
|
|
||||||
def export_headers
|
|
||||||
%w(#domain)
|
|
||||||
end
|
|
||||||
|
|
||||||
def export_data
|
|
||||||
CSV.generate(headers: export_headers, write_headers: true) do |content|
|
|
||||||
DomainAllow.allowed_domains.each do |instance|
|
|
||||||
content << [instance.domain]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,77 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'csv'
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class ExportDomainBlocksController < BaseController
|
|
||||||
include AdminExportControllerConcern
|
|
||||||
|
|
||||||
before_action :set_dummy_import!, only: [:new]
|
|
||||||
|
|
||||||
def new
|
|
||||||
authorize :domain_block, :create?
|
|
||||||
end
|
|
||||||
|
|
||||||
def export
|
|
||||||
authorize :instance, :index?
|
|
||||||
send_export_file
|
|
||||||
end
|
|
||||||
|
|
||||||
def import
|
|
||||||
authorize :domain_block, :create?
|
|
||||||
|
|
||||||
@import = Admin::Import.new(import_params)
|
|
||||||
return render :new unless @import.validate
|
|
||||||
|
|
||||||
@global_private_comment = I18n.t('admin.export_domain_blocks.import.private_comment_template', source: @import.data_file_name, date: I18n.l(Time.now.utc))
|
|
||||||
|
|
||||||
@form = Form::DomainBlockBatch.new
|
|
||||||
@domain_blocks = @import.csv_rows.filter_map do |row|
|
|
||||||
domain = row['#domain'].strip
|
|
||||||
next if DomainBlock.rule_for(domain).present?
|
|
||||||
|
|
||||||
domain_block = DomainBlock.new(domain: domain,
|
|
||||||
severity: row.fetch('#severity', :suspend),
|
|
||||||
reject_media: row.fetch('#reject_media', false),
|
|
||||||
reject_reports: row.fetch('#reject_reports', false),
|
|
||||||
private_comment: @global_private_comment,
|
|
||||||
public_comment: row['#public_comment'],
|
|
||||||
obfuscate: row.fetch('#obfuscate', false))
|
|
||||||
|
|
||||||
if domain_block.invalid?
|
|
||||||
flash.now[:alert] = I18n.t('admin.export_domain_blocks.invalid_domain_block', error: domain_block.errors.full_messages.join(', '))
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
domain_block
|
|
||||||
rescue ArgumentError => e
|
|
||||||
flash.now[:alert] = I18n.t('admin.export_domain_blocks.invalid_domain_block', error: e.message)
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
@warning_domains = Instance.where(domain: @domain_blocks.map(&:domain)).where('EXISTS (SELECT 1 FROM follows JOIN accounts ON follows.account_id = accounts.id OR follows.target_account_id = accounts.id WHERE accounts.domain = instances.domain)').pluck(:domain)
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
flash.now[:alert] = I18n.t('admin.export_domain_blocks.no_file')
|
|
||||||
set_dummy_import!
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def export_filename
|
|
||||||
'domain_blocks.csv'
|
|
||||||
end
|
|
||||||
|
|
||||||
def export_headers
|
|
||||||
%w(#domain #severity #reject_media #reject_reports #public_comment #obfuscate)
|
|
||||||
end
|
|
||||||
|
|
||||||
def export_data
|
|
||||||
CSV.generate(headers: export_headers, write_headers: true) do |content|
|
|
||||||
DomainBlock.with_limitations.each do |instance|
|
|
||||||
content << [instance.domain, instance.severity, instance.reject_media, instance.reject_reports, instance.public_comment, instance.obfuscate]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,55 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class FollowRecommendationsController < BaseController
|
|
||||||
before_action :set_language
|
|
||||||
|
|
||||||
def show
|
|
||||||
authorize :follow_recommendation, :show?
|
|
||||||
|
|
||||||
@form = Form::AccountBatch.new
|
|
||||||
@accounts = filtered_follow_recommendations
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
authorize :follow_recommendation, :show?
|
|
||||||
|
|
||||||
@form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
|
|
||||||
@form.save
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
# Do nothing
|
|
||||||
ensure
|
|
||||||
redirect_to admin_follow_recommendations_path(filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_language
|
|
||||||
@language = follow_recommendation_filter.language
|
|
||||||
end
|
|
||||||
|
|
||||||
def filtered_follow_recommendations
|
|
||||||
follow_recommendation_filter.results
|
|
||||||
end
|
|
||||||
|
|
||||||
def follow_recommendation_filter
|
|
||||||
@follow_recommendation_filter ||= FollowRecommendationFilter.new(filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def form_account_batch_params
|
|
||||||
params.require(:form_account_batch).permit(:action, account_ids: [])
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter_params
|
|
||||||
params.slice(*FollowRecommendationFilter::KEYS).permit(*FollowRecommendationFilter::KEYS)
|
|
||||||
end
|
|
||||||
|
|
||||||
def action_from_button
|
|
||||||
if params[:suppress]
|
|
||||||
'suppress_follow_recommendation'
|
|
||||||
elsif params[:unsuppress]
|
|
||||||
'unsuppress_follow_recommendation'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -3,69 +3,28 @@
|
||||||
module Admin
|
module Admin
|
||||||
class InstancesController < BaseController
|
class InstancesController < BaseController
|
||||||
before_action :set_instances, only: :index
|
before_action :set_instances, only: :index
|
||||||
before_action :set_instance, except: :index
|
before_action :set_instance, only: :show
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :instance, :index?
|
authorize :instance, :index?
|
||||||
preload_delivery_failures!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
authorize :instance, :show?
|
authorize :instance, :show?
|
||||||
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
authorize :instance, :destroy?
|
|
||||||
Admin::DomainPurgeWorker.perform_async(@instance.domain)
|
|
||||||
log_action :destroy, @instance
|
|
||||||
redirect_to admin_instances_path, notice: I18n.t('admin.instances.destroyed_msg', domain: @instance.domain)
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear_delivery_errors
|
|
||||||
authorize :delivery, :clear_delivery_errors?
|
|
||||||
@instance.delivery_failure_tracker.clear_failures!
|
|
||||||
redirect_to admin_instance_path(@instance.domain)
|
|
||||||
end
|
|
||||||
|
|
||||||
def restart_delivery
|
|
||||||
authorize :delivery, :restart_delivery?
|
|
||||||
|
|
||||||
if @instance.unavailable?
|
|
||||||
@instance.delivery_failure_tracker.track_success!
|
|
||||||
log_action :destroy, @instance.unavailable_domain
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_instance_path(@instance.domain)
|
|
||||||
end
|
|
||||||
|
|
||||||
def stop_delivery
|
|
||||||
authorize :delivery, :stop_delivery?
|
|
||||||
unavailable_domain = UnavailableDomain.create!(domain: @instance.domain)
|
|
||||||
log_action :create, unavailable_domain
|
|
||||||
redirect_to admin_instance_path(@instance.domain)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_instance
|
def set_instance
|
||||||
@instance = Instance.find(TagManager.instance.normalize_domain(params[:id]&.strip))
|
@instance = Instance.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_instances
|
def set_instances
|
||||||
@instances = filtered_instances.page(params[:page])
|
@instances = filtered_instances.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def preload_delivery_failures!
|
|
||||||
warning_domains_map = DeliveryFailureTracker.warning_domains_map(@instances.map(&:domain))
|
|
||||||
|
|
||||||
@instances.each do |instance|
|
|
||||||
instance.failure_days = warning_domains_map[instance.domain]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def filtered_instances
|
def filtered_instances
|
||||||
InstanceFilter.new(limited_federation_mode? ? { allowed: true } : filter_params).results
|
InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_params
|
def filter_params
|
||||||
|
|
|
@ -5,7 +5,7 @@ module Admin
|
||||||
def index
|
def index
|
||||||
authorize :ip_block, :index?
|
authorize :ip_block, :index?
|
||||||
|
|
||||||
@ip_blocks = IpBlock.order(ip: :asc).page(params[:page])
|
@ip_blocks = IpBlock.page(params[:page])
|
||||||
@form = Form::IpBlockBatch.new
|
@form = Form::IpBlockBatch.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -29,8 +29,6 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch
|
def batch
|
||||||
authorize :ip_block, :index?
|
|
||||||
|
|
||||||
@form = Form::IpBlockBatch.new(form_ip_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
@form = Form::IpBlockBatch.new(form_ip_block_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
@form.save
|
@form.save
|
||||||
rescue ActionController::ParameterMissing
|
rescue ActionController::ParameterMissing
|
||||||
|
|
52
app/controllers/admin/pending_accounts_controller.rb
Normal file
52
app/controllers/admin/pending_accounts_controller.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class PendingAccountsController < BaseController
|
||||||
|
before_action :set_accounts, only: :index
|
||||||
|
|
||||||
|
def index
|
||||||
|
@form = Form::AccountBatch.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def batch
|
||||||
|
@form = Form::AccountBatch.new(form_account_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
|
@form.save
|
||||||
|
rescue ActionController::ParameterMissing
|
||||||
|
flash[:alert] = I18n.t('admin.accounts.no_account_selected')
|
||||||
|
ensure
|
||||||
|
redirect_to admin_pending_accounts_path(current_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def approve_all
|
||||||
|
Form::AccountBatch.new(current_account: current_account, account_ids: User.pending.pluck(:account_id), action: 'approve').save
|
||||||
|
redirect_to admin_pending_accounts_path(current_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject_all
|
||||||
|
Form::AccountBatch.new(current_account: current_account, account_ids: User.pending.pluck(:account_id), action: 'reject').save
|
||||||
|
redirect_to admin_pending_accounts_path(current_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_accounts
|
||||||
|
@accounts = Account.joins(:user).merge(User.pending.recent).includes(user: :invite_request).page(params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_account_batch_params
|
||||||
|
params.require(:form_account_batch).permit(:action, account_ids: [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_from_button
|
||||||
|
if params[:approve]
|
||||||
|
'approve'
|
||||||
|
elsif params[:reject]
|
||||||
|
'reject'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_params
|
||||||
|
params.slice(:page).permit(:page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,10 +7,9 @@ module Admin
|
||||||
PER_PAGE = 40
|
PER_PAGE = 40
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize @account, :show?
|
authorize :account, :index?
|
||||||
|
|
||||||
@accounts = RelationshipFilter.new(@account, filter_params).results.includes(:account_stat, user: [:ips, :invite_request]).page(params[:page]).per(PER_PAGE)
|
@accounts = RelationshipFilter.new(@account, filter_params).results.page(params[:page]).per(PER_PAGE)
|
||||||
@form = Form::AccountBatch.new
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
module Admin
|
module Admin
|
||||||
class RelaysController < BaseController
|
class RelaysController < BaseController
|
||||||
before_action :set_relay, except: [:index, :new, :create]
|
before_action :set_relay, except: [:index, :new, :create]
|
||||||
before_action :warn_signatures_not_enabled!, only: [:new, :create, :enable]
|
before_action :require_signatures_enabled!, only: [:new, :create, :enable]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :relay, :update?
|
authorize :relay, :update?
|
||||||
|
@ -56,8 +56,8 @@ module Admin
|
||||||
params.require(:relay).permit(:inbox_url)
|
params.require(:relay).permit(:inbox_url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def warn_signatures_not_enabled!
|
def require_signatures_enabled!
|
||||||
flash.now[:error] = I18n.t('admin.relays.signatures_not_enabled') if authorized_fetch_mode?
|
redirect_to admin_relays_path, alert: I18n.t('admin.relays.signatures_not_enabled') if authorized_fetch_mode?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,17 +14,20 @@ module Admin
|
||||||
if params[:create_and_resolve]
|
if params[:create_and_resolve]
|
||||||
@report.resolve!(current_account)
|
@report.resolve!(current_account)
|
||||||
log_action :resolve, @report
|
log_action :resolve, @report
|
||||||
elsif params[:create_and_unresolve]
|
|
||||||
|
redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:create_and_unresolve]
|
||||||
@report.unresolve!
|
@report.unresolve!
|
||||||
log_action :reopen, @report
|
log_action :reopen, @report
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to after_create_redirect_path, notice: I18n.t('admin.report_notes.created_msg')
|
redirect_to admin_report_path(@report), notice: I18n.t('admin.report_notes.created_msg')
|
||||||
else
|
else
|
||||||
@report_notes = @report.notes.includes(:account).order(id: :desc)
|
@report_notes = (@report.notes.latest + @report.history + @report.target_account.targeted_account_warnings.latest.custom).sort_by(&:created_at)
|
||||||
@action_logs = @report.history.includes(:target)
|
@form = Form::StatusBatch.new
|
||||||
@form = Admin::StatusBatchAction.new
|
|
||||||
@statuses = @report.statuses.with_includes
|
|
||||||
|
|
||||||
render template: 'admin/reports/show'
|
render template: 'admin/reports/show'
|
||||||
end
|
end
|
||||||
|
@ -38,14 +41,6 @@ module Admin
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def after_create_redirect_path
|
|
||||||
if params[:create_and_resolve]
|
|
||||||
admin_reports_path
|
|
||||||
else
|
|
||||||
admin_report_path(@report)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:report_note).permit(
|
params.require(:report_note).permit(
|
||||||
:content,
|
:content,
|
||||||
|
|
44
app/controllers/admin/reported_statuses_controller.rb
Normal file
44
app/controllers/admin/reported_statuses_controller.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class ReportedStatusesController < BaseController
|
||||||
|
before_action :set_report
|
||||||
|
|
||||||
|
def create
|
||||||
|
authorize :status, :update?
|
||||||
|
|
||||||
|
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
|
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
||||||
|
|
||||||
|
redirect_to admin_report_path(@report)
|
||||||
|
rescue ActionController::ParameterMissing
|
||||||
|
flash[:alert] = I18n.t('admin.statuses.no_status_selected')
|
||||||
|
|
||||||
|
redirect_to admin_report_path(@report)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def status_params
|
||||||
|
params.require(:status).permit(:sensitive)
|
||||||
|
end
|
||||||
|
|
||||||
|
def form_status_batch_params
|
||||||
|
params.require(:form_status_batch).permit(status_ids: [])
|
||||||
|
end
|
||||||
|
|
||||||
|
def action_from_button
|
||||||
|
if params[:nsfw_on]
|
||||||
|
'nsfw_on'
|
||||||
|
elsif params[:nsfw_off]
|
||||||
|
'nsfw_off'
|
||||||
|
elsif params[:delete]
|
||||||
|
'delete'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_report
|
||||||
|
@report = Report.find(params[:report_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,63 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Admin::Reports::ActionsController < Admin::BaseController
|
|
||||||
before_action :set_report
|
|
||||||
|
|
||||||
def preview
|
|
||||||
authorize @report, :show?
|
|
||||||
@moderation_action = action_from_button
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
authorize @report, :show?
|
|
||||||
|
|
||||||
case action_from_button
|
|
||||||
when 'delete', 'mark_as_sensitive'
|
|
||||||
status_batch_action = Admin::StatusBatchAction.new(
|
|
||||||
type: action_from_button,
|
|
||||||
status_ids: @report.status_ids,
|
|
||||||
current_account: current_account,
|
|
||||||
report_id: @report.id,
|
|
||||||
send_email_notification: !@report.spam?,
|
|
||||||
text: params[:text]
|
|
||||||
)
|
|
||||||
|
|
||||||
status_batch_action.save!
|
|
||||||
when 'silence', 'suspend'
|
|
||||||
account_action = Admin::AccountAction.new(
|
|
||||||
type: action_from_button,
|
|
||||||
report_id: @report.id,
|
|
||||||
target_account: @report.target_account,
|
|
||||||
current_account: current_account,
|
|
||||||
send_email_notification: !@report.spam?,
|
|
||||||
text: params[:text]
|
|
||||||
)
|
|
||||||
|
|
||||||
account_action.save!
|
|
||||||
else
|
|
||||||
return redirect_to admin_report_path(@report), alert: I18n.t('admin.reports.unknown_action_msg', action: action_from_button)
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_reports_path, notice: I18n.t('admin.reports.processed_msg', id: @report.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_report
|
|
||||||
@report = Report.find(params[:report_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def action_from_button
|
|
||||||
if params[:delete]
|
|
||||||
'delete'
|
|
||||||
elsif params[:mark_as_sensitive]
|
|
||||||
'mark_as_sensitive'
|
|
||||||
elsif params[:silence]
|
|
||||||
'silence'
|
|
||||||
elsif params[:suspend]
|
|
||||||
'suspend'
|
|
||||||
elsif params[:moderation_action]
|
|
||||||
params[:moderation_action]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -13,10 +13,8 @@ module Admin
|
||||||
authorize @report, :show?
|
authorize @report, :show?
|
||||||
|
|
||||||
@report_note = @report.notes.new
|
@report_note = @report.notes.new
|
||||||
@report_notes = @report.notes.includes(:account).order(id: :desc)
|
@report_notes = (@report.notes.latest + @report.history + @report.target_account.targeted_account_warnings.latest.custom).sort_by(&:created_at)
|
||||||
@action_logs = @report.history.includes(:target)
|
@form = Form::StatusBatch.new
|
||||||
@form = Admin::StatusBatchAction.new
|
|
||||||
@statuses = @report.statuses.with_includes
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def assign_to_self
|
def assign_to_self
|
||||||
|
|
|
@ -6,9 +6,9 @@ module Admin
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @user, :reset_password?
|
authorize @user, :reset_password?
|
||||||
@user.reset_password!
|
@user.send_reset_password_instructions
|
||||||
log_action :reset_password, @user
|
log_action :reset_password, @user
|
||||||
redirect_to admin_account_path(@user.account_id)
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,66 +2,20 @@
|
||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class RolesController < BaseController
|
class RolesController < BaseController
|
||||||
before_action :set_role, except: [:index, :new, :create]
|
before_action :set_user
|
||||||
|
|
||||||
def index
|
def promote
|
||||||
authorize :user_role, :index?
|
authorize @user, :promote?
|
||||||
|
@user.promote!
|
||||||
@roles = UserRole.order(position: :desc).page(params[:page])
|
log_action :promote, @user
|
||||||
|
redirect_to admin_account_path(@user.account_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def demote
|
||||||
authorize :user_role, :create?
|
authorize @user, :demote?
|
||||||
|
@user.demote!
|
||||||
@role = UserRole.new
|
log_action :demote, @user
|
||||||
end
|
redirect_to admin_account_path(@user.account_id)
|
||||||
|
|
||||||
def edit
|
|
||||||
authorize @role, :update?
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
authorize :user_role, :create?
|
|
||||||
|
|
||||||
@role = UserRole.new(resource_params)
|
|
||||||
@role.current_account = current_account
|
|
||||||
|
|
||||||
if @role.save
|
|
||||||
log_action :create, @role
|
|
||||||
redirect_to admin_roles_path
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
authorize @role, :update?
|
|
||||||
|
|
||||||
@role.current_account = current_account
|
|
||||||
|
|
||||||
if @role.update(resource_params)
|
|
||||||
log_action :update, @role
|
|
||||||
redirect_to admin_roles_path
|
|
||||||
else
|
|
||||||
render :edit
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
authorize @role, :destroy?
|
|
||||||
@role.destroy!
|
|
||||||
log_action :destroy, @role
|
|
||||||
redirect_to admin_roles_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_role
|
|
||||||
@role = UserRole.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.require(:user_role).permit(:name, :color, :highlighted, :position, permissions_as_keys: [])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue