Merge remote-tracking branch 'catstodon/feature/emoji_reactions'

This commit is contained in:
Erin Shepherd 2023-07-02 21:08:23 +02:00
commit fe8b6e023a
2226 changed files with 47326 additions and 23281 deletions

View file

@ -1,128 +0,0 @@
version: 2.1
orbs:
ruby: circleci/ruby@2.0.0
node: circleci/node@5.0.3
executors:
default:
parameters:
ruby-version:
type: string
docker:
- image: cimg/ruby:<< parameters.ruby-version >>
environment:
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
CONTINUOUS_INTEGRATION: true
DB_HOST: localhost
DB_USER: root
DISABLE_SIMPLECOV: true
RAILS_ENV: test
- image: cimg/postgres:14.5
environment:
POSTGRES_USER: root
POSTGRES_HOST_AUTH_METHOD: trust
- image: cimg/redis:7.0
commands:
install-system-dependencies:
steps:
- run:
name: Install system dependencies
command: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
install-ruby-dependencies:
parameters:
ruby-version:
type: string
steps:
- run:
command: |
bundle config clean 'true'
bundle config frozen 'true'
bundle config without 'development production'
name: Set bundler settings
- ruby/install-deps:
bundler-version: '2.3.26'
key: ruby<< parameters.ruby-version >>-gems-v2
wait-db:
steps:
- run:
command: dockerize -wait tcp://localhost:5432 -wait tcp://localhost:6379 -timeout 1m
name: Wait for PostgreSQL and Redis
jobs:
build:
docker:
- image: cimg/ruby:3.2-node
environment:
RAILS_ENV: test
steps:
- checkout
- install-system-dependencies
- install-ruby-dependencies:
ruby-version: '3.2'
- node/install-packages:
cache-version: v1
pkg-manager: yarn
- run:
command: |
export NODE_OPTIONS=--openssl-legacy-provider
./bin/rails assets:precompile
name: Precompile assets
- persist_to_workspace:
paths:
- public/assets
- public/packs-test
root: .
test:
parameters:
ruby-version:
type: string
executor:
name: default
ruby-version: << parameters.ruby-version >>
environment:
ALLOW_NOPAM: true
PAM_ENABLED: true
PAM_DEFAULT_SERVICE: pam_test
PAM_CONTROLLED_SERVICE: pam_test_controlled
parallelism: 4
steps:
- checkout
- install-system-dependencies
- run:
command: sudo apt-get install -y ffmpeg imagemagick libmagickcore-dev libmagickwand-dev libjpeg-dev libpng-dev libtiff-dev libwebp-dev libpam-dev
name: Install additional system dependencies
- run:
command: bundle config with 'pam_authentication'
name: Enable PAM authentication
- install-ruby-dependencies:
ruby-version: << parameters.ruby-version >>
- attach_workspace:
at: .
- wait-db
- run:
command: ./bin/rails db:create db:schema:load db:seed
name: Load database schema
- ruby/rspec-test
workflows:
version: 2
build-and-test:
jobs:
- build
- test:
matrix:
parameters:
ruby-version:
- '2.7'
- '3.0'
- '3.1'
- '3.2'
name: test-ruby<< matrix.ruby-version >>
requires:
- build

View file

@ -1,39 +0,0 @@
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: false
eslint:
enabled: false
rubocop:
enabled: false
sass-lint:
enabled: false
exclude_patterns:
- spec/
- vendor/asset/
- app/javascript/mastodon/locales/**/*.json
- config/locales/**/*.yml

View file

@ -1,16 +1,14 @@
# [Choice] Ruby version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.1, 3.0, 2, 2.7, 2.6, 3-bullseye, 3.1-bullseye, 3.0-bullseye, 2-bullseye, 2.7-bullseye, 2.6-bullseye, 3-buster, 3.1-buster, 3.0-buster, 2-buster, 2.7-buster, 2.6-buster # For details, see https://github.com/devcontainers/images/tree/main/src/ruby
ARG VARIANT=3.1-bullseye FROM mcr.microsoft.com/devcontainers/ruby:0-3.2-bullseye
FROM mcr.microsoft.com/vscode/devcontainers/ruby:${VARIANT}
# Install Rails # Install Rails
# RUN gem install rails webdrivers # RUN gem install rails webdrivers
# Default value to allow debug server to serve content over GitHub Codespace's port forwarding service # Default value to allow debug server to serve content over GitHub Codespace's port forwarding service
# The value is a comma-separated list of allowed domains # The value is a comma-separated list of allowed domains
ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev" ENV RAILS_DEVELOPMENT_HOSTS=".githubpreview.dev,.preview.app.github.dev,.app.github.dev"
# [Choice] Node.js version: lts/*, 18, 16, 14 ARG NODE_VERSION="16"
ARG NODE_VERSION="lts/*"
RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1" 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. # [Optional] Uncomment this section to install additional OS packages.
@ -22,3 +20,5 @@ RUN gem install foreman
# [Optional] Uncomment this line to install global node packages. # [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 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

View file

@ -1,30 +1,13 @@
// For more details, see https://aka.ms/devcontainer.json.
{ {
"name": "Mastodon", "name": "Mastodon",
"dockerComposeFile": "docker-compose.yml", "dockerComposeFile": "docker-compose.yml",
"service": "app", "service": "app",
"workspaceFolder": "/mastodon", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
// Configure tool-specific properties.
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"EditorConfig.EditorConfig",
"dbaeumer.vscode-eslint",
"rebornix.Ruby",
"webben.browserslist"
]
}
},
// Features to add to the dev container. More info: https://containers.dev/features.
"features": { "features": {
"ghcr.io/devcontainers/features/sshd:1": { "ghcr.io/devcontainers/features/sshd:1": {}
"version": "latest"
}
}, },
// Use 'forwardPorts' to make a list of ports inside the container available locally. // Use 'forwardPorts' to make a list of ports inside the container available locally.
@ -32,8 +15,18 @@
"forwardPorts": [3000, 4000], "forwardPorts": [3000, 4000],
// Use 'postCreateCommand' to run commands after the container is created. // Use 'postCreateCommand' to run commands after the container is created.
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
"postCreateCommand": ".devcontainer/post-create.sh", "postCreateCommand": ".devcontainer/post-create.sh",
"waitFor": "postCreateCommand",
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. // Configure tool-specific properties.
"remoteUser": "vscode" "customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Set *default* container specific settings.json values on container create.
"settings": {},
// Add the IDs of extensions you want installed when the container is created.
"extensions": ["EditorConfig.EditorConfig", "webben.browserslist"]
}
}
} }

View file

@ -5,19 +5,12 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
args:
# Update 'VARIANT' to pick a version of Ruby: 3, 3.1, 3.0, 2, 2.7, 2.6
# Append -bullseye or -buster to pin to an OS version.
# Use -bullseye variants on local arm64/Apple Silicon.
VARIANT: '3.0-bullseye'
# Optional Node.js version to install
NODE_VERSION: '16'
volumes: volumes:
- ..:/mastodon:cached - ../..:/workspaces:cached
environment: environment:
RAILS_ENV: development RAILS_ENV: development
NODE_ENV: development NODE_ENV: development
BIND: 0.0.0.0
REDIS_HOST: redis REDIS_HOST: redis
REDIS_PORT: '6379' REDIS_PORT: '6379'
DB_HOST: db DB_HOST: db
@ -30,10 +23,12 @@ services:
LIBRE_TRANSLATE_ENDPOINT: http://libretranslate:5000 LIBRE_TRANSLATE_ENDPOINT: http://libretranslate:5000
# Overrides default command so things don't shut down after the process ends. # Overrides default command so things don't shut down after the process ends.
command: sleep infinity command: sleep infinity
ports:
- '127.0.0.1:3000:3000'
- '127.0.0.1:4000:4000'
networks: networks:
- external_network - external_network
- internal_network - internal_network
user: vscode
db: db:
image: postgres:14-alpine image: postgres:14-alpine
@ -49,7 +44,7 @@ services:
- internal_network - internal_network
redis: redis:
image: redis:6-alpine image: redis:7-alpine
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- redis-data:/data - redis-data:/data
@ -74,15 +69,19 @@ services:
hard: -1 hard: -1
libretranslate: libretranslate:
image: libretranslate/libretranslate:v1.2.9 image: libretranslate/libretranslate:v1.3.10
restart: unless-stopped restart: unless-stopped
volumes:
- lt-data:/home/libretranslate/.local
networks: networks:
- external_network
- internal_network - internal_network
volumes: volumes:
postgres-data: postgres-data:
redis-data: redis-data:
es-data: es-data:
lt-data:
networks: networks:
external_network: external_network:

View file

@ -3,17 +3,22 @@
set -e # Fail the whole script on first error set -e # Fail the whole script on first error
# Fetch Ruby gem dependencies # Fetch Ruby gem dependencies
bundle install --path vendor/bundle --with='development test' bundle config path 'vendor/bundle'
bundle config with 'development test'
# Fetch Javascript dependencies bundle install
yarn install
# Make Gemfile.lock pristine again # Make Gemfile.lock pristine again
git checkout -- Gemfile.lock git checkout -- Gemfile.lock
# Fetch Javascript dependencies
yarn --frozen-lockfile
# [re]create, migrate, and seed the test database # [re]create, migrate, and seed the test database
RAILS_ENV=test ./bin/rails db:setup 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 # Precompile assets for development
RAILS_ENV=development ./bin/rails assets:precompile RAILS_ENV=development ./bin/rails assets:precompile

View file

@ -0,0 +1,8 @@
👋 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.

View file

@ -4,74 +4,65 @@ module.exports = {
extends: [ extends: [
'eslint:recommended', 'eslint:recommended',
'plugin:react/recommended', 'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended', 'plugin:jsx-a11y/recommended',
'plugin:import/recommended', 'plugin:import/recommended',
'plugin:promise/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: '@babel/eslint-parser', parser: '@typescript-eslint/parser',
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: 2021,
requireConfigFile: false,
babelOptions: {
configFile: false,
presets: ['@babel/react', '@babel/env'],
},
}, },
settings: { settings: {
react: { react: {
version: 'detect', version: 'detect',
}, },
'import/extensions': [
'.js', '.jsx',
],
'import/ignore': [ 'import/ignore': [
'node_modules', 'node_modules',
'\\.(css|scss|json)$', '\\.(css|scss|json)$',
], ],
'import/resolver': { 'import/resolver': {
node: { typescript: {},
paths: ['app/javascript'],
extensions: ['.js', '.jsx'],
},
}, },
}, },
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', eqeqeq: ['error', 'always', { 'null': 'ignore' }],
indent: ['warn', 2],
'jsx-quotes': ['error', 'prefer-single'], 'jsx-quotes': ['error', 'prefer-single'],
'no-case-declarations': 'off', 'no-case-declarations': 'off',
'no-catch-shadow': 'error', 'no-catch-shadow': 'error',
@ -91,40 +82,25 @@ module.exports = {
{ property: 'substr', message: 'Use .slice instead of .substr.' }, { property: 'substr', message: 'Use .slice instead of .substr.' },
], ],
'no-self-assign': 'off', 'no-self-assign': 'off',
'no-trailing-spaces': 'warn',
'no-unused-expressions': 'error', 'no-unused-expressions': 'error',
'no-unused-vars': [ 'no-unused-vars': 'off',
'@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',
'valid-typeof': 'error', 'valid-typeof': 'error',
'react/jsx-filename-extension': ['error', { 'allow': 'as-needed' }], 'react/jsx-filename-extension': ['error', { extensions: ['.jsx', 'tsx'] }],
'react/jsx-boolean-value': 'error', 'react/jsx-boolean-value': 'error',
'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
'react/jsx-curly-spacing': 'error',
'react/display-name': 'off', 'react/display-name': 'off',
'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-target-blank': 'off', 'react/jsx-no-target-blank': 'off',
'react/jsx-tag-spacing': 'error',
'react/jsx-wrap-multilines': 'error',
'react/no-deprecated': 'off',
'react/no-unknown-property': 'off', 'react/no-unknown-property': 'off',
'react/self-closing-comp': 'error', 'react/self-closing-comp': 'error',
@ -188,19 +164,31 @@ module.exports = {
{ {
js: 'never', js: 'never',
jsx: '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-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',
'promise/always-return': 'off', 'promise/always-return': 'off',
@ -213,5 +201,163 @@ module.exports = {
'promise/no-callback-in-promise': 'off', 'promise/no-callback-in-promise': 'off',
'promise/no-nesting': 'off', 'promise/no-nesting': 'off',
'promise/no-promise-in-callback': '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/**/*',
],
env: {
commonjs: true,
},
parserOptions: {
sourceType: 'script',
},
rules: {
'import/no-commonjs': 'off',
},
},
{
files: [
'**/*.ts',
'**/*.tsx',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:jsx-a11y/recommended',
'plugin:import/recommended',
'plugin:import/typescript',
'plugin:promise/recommended',
'plugin:jsdoc/recommended',
'plugin:prettier/recommended',
],
parserOptions: {
project: './tsconfig.json',
tsconfigRootDir: __dirname,
},
rules: {
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
'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,prop-types}',
group: 'builtin',
position: 'after',
},
// I18n
{
pattern: 'react-intl',
group: 'builtin',
position: 'after',
},
// Common React utilities
{
pattern: '{classnames,react-helmet}',
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/**,flavours/glitch-soc/**}',
group: 'internal',
position: 'after',
},
],
pathGroupsExcludedImportTypes: [],
},
],
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
'@typescript-eslint/consistent-type-exports': 'error',
'@typescript-eslint/consistent-type-imports': 'error',
'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' }],
},
},
{
files: [
'**/__tests__/*.js',
'**/__tests__/*.jsx',
],
env: {
jest: true,
},
},
{
files: [
'streaming/**/*',
],
rules: {
'import/no-commonjs': 'off',
},
},
],
}; };

View file

@ -25,12 +25,15 @@ jobs:
- uses: hadolint/hadolint-action@v3.1.0 - uses: hadolint/hadolint-action@v3.1.0
- uses: docker/setup-qemu-action@v2 - uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2 - uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
- name: Log in to the Github Container registry
uses: docker/login-action@v2
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
- uses: docker/metadata-action@v4 - uses: docker/metadata-action@v4
id: meta id: meta
with: with:
@ -39,13 +42,22 @@ jobs:
type=raw,value=latest,enable={{is_default_branch}} type=raw,value=latest,enable={{is_default_branch}}
type=edge,branch=main type=edge,branch=main
type=sha,prefix=,format=long type=sha,prefix=,format=long
- name: Generate version suffix
id: version_vars
if: github.repository == 'mastodon/mastodon' && github.event_name == 'push' && github.ref_name == 'main'
run: |
echo mastodon_version_suffix=+edge-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
- uses: docker/build-push-action@v4 - uses: docker/build-push-action@v4
with: with:
context: . context: .
build-args: MASTODON_VERSION_SUFFIX=${{ steps.version_vars.outputs.mastodon_version_suffix }}
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
provenance: false provenance: false
builder: ${{ steps.buildx.outputs.name }} builder: ${{ steps.buildx.outputs.name }}
push: ${{ github.event_name != 'pull_request' }} push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max

60
.github/workflows/build-nightly.yml vendored Normal file
View file

@ -0,0 +1,60 @@
name: Build nightly container image
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * *' # run at 2 AM UTC
permissions:
contents: read
packages: write
jobs:
build-nightly-image:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
steps:
- uses: actions/checkout@v3
- uses: hadolint/hadolint-action@v3.1.0
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- name: Log in to the Github Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v4
id: meta
with:
images: |
ghcr.io/mastodon/mastodon
flavor: |
latest=auto
tags: |
type=raw,value=nightly
type=schedule,pattern=nightly-{{date 'YYYY-MM-DD' tz='Etc/UTC'}}
labels: |
org.opencontainers.image.description=Nightly build image used for testing purposes
- name: Generate version suffix
id: version_vars
run: |
echo mastodon_version_suffix=+nightly-$(date +'%Y%m%d') >> $GITHUB_OUTPUT
- uses: docker/build-push-action@v4
with:
context: .
build-args: MASTODON_VERSION_SUFFIX=${{ steps.version_vars.outputs.mastodon_version_suffix }}
platforms: linux/amd64,linux/arm64
provenance: false
builder: ${{ steps.buildx.outputs.name }}
push: ${{ github.repository == 'mastodon/mastodon' && github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

View file

@ -30,13 +30,28 @@ jobs:
ruby-version: .ruby-version ruby-version: .ruby-version
bundler-cache: true bundler-cache: true
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Check for missing strings in English JSON
run: |
yarn build:development
yarn manage:translations en
git diff --exit-code
- name: Check locale file normalization - name: Check locale file normalization
run: bundle exec i18n-tasks check-normalized run: bundle exec i18n-tasks check-normalized
- name: Check for unused strings - name: Check for unused strings
run: bundle exec i18n-tasks unused run: bundle exec i18n-tasks unused
- name: Check for missing strings in English - name: Check for missing strings in English YML
run: | run: |
bundle exec i18n-tasks add-missing -l en bundle exec i18n-tasks add-missing -l en
git diff --exit-code git diff --exit-code

View file

@ -0,0 +1,17 @@
{
"problemMatcher": [
{
"owner": "haml-lint",
"severity": "warning",
"pattern": [
{
"regexp": "^(.*):(\\d+)\\s\\[W]\\s(.*):\\s(.*)$",
"file": 1,
"line": 2,
"code": 3,
"message": 4
}
]
}
]
}

46
.github/workflows/lint-haml.yml vendored Normal file
View file

@ -0,0 +1,46 @@
name: Haml Linting
on:
push:
branches-ignore:
- 'dependabot/**'
paths:
- '.github/workflows/haml-lint-problem-matcher.json'
- '.github/workflows/lint-haml.yml'
- '.haml-lint*.yml'
- '.rubocop*.yml'
- '.ruby-version'
- '**/*.haml'
- 'Gemfile*'
pull_request:
paths:
- '.github/workflows/haml-lint-problem-matcher.json'
- '.github/workflows/lint-haml.yml'
- '.haml-lint*.yml'
- '.rubocop*.yml'
- '.ruby-version'
- '**/*.haml'
- 'Gemfile*'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v3
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Run haml-lint
run: |
echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json"
bundle exec haml-lint

View file

@ -6,22 +6,28 @@ on:
paths: paths:
- 'package.json' - 'package.json'
- 'yarn.lock' - 'yarn.lock'
- 'tsconfig.json'
- '.nvmrc' - '.nvmrc'
- '.prettier*' - '.prettier*'
- '.eslint*' - '.eslint*'
- '**/*.js' - '**/*.js'
- '**/*.jsx' - '**/*.jsx'
- '**/*.ts'
- '**/*.tsx'
- '.github/workflows/lint-js.yml' - '.github/workflows/lint-js.yml'
pull_request: pull_request:
paths: paths:
- 'package.json' - 'package.json'
- 'yarn.lock' - 'yarn.lock'
- 'tsconfig.json'
- '.nvmrc' - '.nvmrc'
- '.prettier*' - '.prettier*'
- '.eslint*' - '.eslint*'
- '**/*.js' - '**/*.js'
- '**/*.jsx' - '**/*.jsx'
- '**/*.ts'
- '**/*.tsx'
- '.github/workflows/lint-js.yml' - '.github/workflows/lint-js.yml'
jobs: jobs:
@ -42,4 +48,7 @@ jobs:
run: yarn --frozen-lockfile run: yarn --frozen-lockfile
- name: ESLint - name: ESLint
run: yarn test:lint:js run: yarn test:lint:js --max-warnings 0
- name: Typecheck
run: yarn test:typecheck

View file

@ -2,7 +2,13 @@ name: PR Needs Rebase
on: on:
push: push:
branches-ignore:
- 'dependabot/**'
- 'l10n_main'
pull_request_target: pull_request_target:
branches-ignore:
- 'dependabot/**'
- 'l10n_main'
types: [synchronize] types: [synchronize]
permissions: permissions:

View file

@ -9,6 +9,8 @@ on:
- '.nvmrc' - '.nvmrc'
- '**/*.js' - '**/*.js'
- '**/*.jsx' - '**/*.jsx'
- '**/*.ts'
- '**/*.tsx'
- '**/*.snap' - '**/*.snap'
- '.github/workflows/test-js.yml' - '.github/workflows/test-js.yml'
@ -19,6 +21,8 @@ on:
- '.nvmrc' - '.nvmrc'
- '**/*.js' - '**/*.js'
- '**/*.jsx' - '**/*.jsx'
- '**/*.ts'
- '**/*.tsx'
- '**/*.snap' - '**/*.snap'
- '.github/workflows/test-js.yml' - '.github/workflows/test-js.yml'

View file

@ -16,16 +16,24 @@ jobs:
- id: skip_check - id: skip_check
uses: fkirc/skip-duplicate-actions@v5 uses: fkirc/skip-duplicate-actions@v5
with: with:
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml"]' paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml", "lib/tasks/tests.rake"]'
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre_job needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true' if: needs.pre_job.outputs.should_skip != 'true'
strategy:
fail-fast: false
matrix:
postgres:
- 14-alpine
- 15-alpine
services: services:
postgres: postgres:
image: postgres:14.5 image: postgres:${{ matrix.postgres}}
env: env:
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres POSTGRES_USER: postgres
@ -38,7 +46,7 @@ jobs:
- 5432:5432 - 5432:5432
redis: redis:
image: redis:7.0 image: redis:7-alpine
options: >- options: >-
--health-cmd "redis-cli ping" --health-cmd "redis-cli ping"
--health-interval 10s --health-interval 10s
@ -64,7 +72,9 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Install native Ruby dependencies - name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache - name: Set up bundler cache
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1

View file

@ -16,16 +16,24 @@ jobs:
- id: skip_check - id: skip_check
uses: fkirc/skip-duplicate-actions@v5 uses: fkirc/skip-duplicate-actions@v5
with: with:
paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml"]' paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml", "lib/tasks/tests.rake"]'
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: pre_job needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true' if: needs.pre_job.outputs.should_skip != 'true'
strategy:
fail-fast: false
matrix:
postgres:
- 14-alpine
- 15-alpine
services: services:
postgres: postgres:
image: postgres:14.5 image: postgres:${{ matrix.postgres}}
env: env:
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres POSTGRES_USER: postgres
@ -37,7 +45,7 @@ jobs:
ports: ports:
- 5432:5432 - 5432:5432
redis: redis:
image: redis:7.0 image: redis:7-alpine
options: >- options: >-
--health-cmd "redis-cli ping" --health-cmd "redis-cli ping"
--health-interval 10s --health-interval 10s
@ -63,7 +71,9 @@ jobs:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Install native Ruby dependencies - name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache - name: Set up bundler cache
uses: ruby/setup-ruby@v1 uses: ruby/setup-ruby@v1

150
.github/workflows/test-ruby.yml vendored Normal file
View file

@ -0,0 +1,150 @@
name: Ruby Testing
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
env:
BUNDLE_CLEAN: true
BUNDLE_FROZEN: true
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
mode:
- production
- test
env:
RAILS_ENV: ${{ matrix.mode }}
BUNDLE_WITH: ${{ matrix.mode }}
OTP_SECRET: precompile_placeholder
SECRET_KEY_BASE: precompile_placeholder
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- run: yarn --frozen-lockfile --production
- name: Precompile assets
# Previously had set this, but it's not supported
# export NODE_OPTIONS=--openssl-legacy-provider
run: |-
./bin/rails assets:precompile
- uses: actions/upload-artifact@v3
if: matrix.mode == 'test'
with:
path: |-
./public/assets
./public/packs-test
name: ${{ github.sha }}
retention-days: 0
test:
runs-on: ubuntu-latest
needs:
- build
services:
postgres:
image: postgres:14-alpine
env:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 6379:6379
env:
DB_HOST: localhost
DB_USER: postgres
DB_PASS: postgres
DISABLE_SIMPLECOV: true
RAILS_ENV: test
ALLOW_NOPAM: true
PAM_ENABLED: true
PAM_DEFAULT_SERVICE: pam_test
PAM_CONTROLLED_SERVICE: pam_test_controlled
BUNDLE_WITH: 'pam_authentication test'
CI_JOBS: ${{ matrix.ci_job }}/4
strategy:
fail-fast: false
matrix:
ruby-version:
- '3.0'
- '3.1'
- '.ruby-version'
ci_job:
- 1
- 2
- 3
- 4
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
path: './public'
name: ${{ github.sha }}
- name: Update package index
run: sudo apt-get update
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick libpam-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version}}
bundler-cache: true
- name: Load database schema
run: './bin/rails db:create db:schema:load db:seed'
- run: bundle exec rake rspec_chunked

View file

@ -1,108 +1,9 @@
# Whether to ignore frontmatter at the beginning of HAML documents for inherits_from: .haml-lint_todo.yml
# frameworks such as Jekyll/Middleman
skip_frontmatter: false
exclude: exclude:
- 'vendor/**/*' - 'vendor/**/*'
- 'spec/**/*' - lib/templates/haml/scaffold/_form.html.haml
- 'lib/templates/**/*'
- 'app/views/kaminari/**/*'
linters: linters:
AltText: AltText:
enabled: false
ClassAttributeWithStaticValue:
enabled: true
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

106
.haml-lint_todo.yml Normal file
View file

@ -0,0 +1,106 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
# on 2023-03-15 00:55:01 -0400 using Haml-Lint version 0.45.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: 63
RuboCop:
exclude:
- 'app/views/accounts/_og.html.haml'
- 'app/views/admin/account_warnings/_account_warning.html.haml'
- 'app/views/admin/accounts/index.html.haml'
- 'app/views/admin/accounts/show.html.haml'
- 'app/views/admin/announcements/edit.html.haml'
- 'app/views/admin/announcements/new.html.haml'
- 'app/views/admin/disputes/appeals/_appeal.html.haml'
- 'app/views/admin/domain_blocks/edit.html.haml'
- 'app/views/admin/domain_blocks/new.html.haml'
- 'app/views/admin/ip_blocks/new.html.haml'
- 'app/views/admin/reports/actions/preview.html.haml'
- 'app/views/admin/reports/index.html.haml'
- 'app/views/admin/reports/show.html.haml'
- 'app/views/admin/roles/_form.html.haml'
- 'app/views/admin/settings/about/show.html.haml'
- 'app/views/admin/settings/appearance/show.html.haml'
- 'app/views/admin/settings/registrations/show.html.haml'
- 'app/views/admin/statuses/show.html.haml'
- 'app/views/auth/registrations/new.html.haml'
- 'app/views/disputes/strikes/show.html.haml'
- 'app/views/filters/_filter_fields.html.haml'
- 'app/views/invites/_form.html.haml'
- 'app/views/layouts/application.html.haml'
- 'app/views/layouts/error.html.haml'
- 'app/views/notification_mailer/_status.html.haml'
- 'app/views/settings/applications/_fields.html.haml'
- 'app/views/settings/imports/show.html.haml'
- 'app/views/settings/preferences/appearance/show.html.haml'
- 'app/views/settings/preferences/other/show.html.haml'
- 'app/views/statuses/_detailed_status.html.haml'
- 'app/views/statuses/_poll.html.haml'
- 'app/views/statuses/show.html.haml'
- 'app/views/statuses_cleanup/show.html.haml'
- 'app/views/user_mailer/warning.html.haml'
# Offense count: 913
LineLength:
enabled: false
# Offense count: 22
UnnecessaryStringOutput:
exclude:
- 'app/views/accounts/show.html.haml'
- 'app/views/admin/custom_emojis/_custom_emoji.html.haml'
- 'app/views/admin/relays/_relay.html.haml'
- 'app/views/admin/rules/_rule.html.haml'
- 'app/views/admin/statuses/index.html.haml'
- 'app/views/auth/registrations/_sessions.html.haml'
- 'app/views/disputes/strikes/show.html.haml'
- 'app/views/notification_mailer/_status.html.haml'
- 'app/views/settings/two_factor_authentication_methods/index.html.haml'
- 'app/views/statuses/_detailed_status.html.haml'
- 'app/views/statuses/_poll.html.haml'
- 'app/views/statuses/_simple_status.html.haml'
- 'app/views/user_mailer/suspicious_sign_in.html.haml'
- 'app/views/user_mailer/webauthn_credential_added.html.haml'
- 'app/views/user_mailer/webauthn_credential_deleted.html.haml'
- 'app/views/user_mailer/welcome.html.haml'
# 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: 41
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/_sessions.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'
- 'app/views/statuses/_status.html.haml'
# Offense count: 6
ConsecutiveSilentScripts:
exclude:
- 'app/views/admin/settings/shared/_links.html.haml'
- 'app/views/settings/login_activities/_login_activity.html.haml'
- 'app/views/statuses/_poll.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'

4
.husky/pre-commit Executable file
View file

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint-staged

2
.nvmrc
View file

@ -1 +1 @@
16.19 16.20

View file

@ -1,3 +1,4 @@
module.exports = { module.exports = {
singleQuote: true singleQuote: true,
jsxSingleQuote: true
} }

View file

@ -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 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

View file

@ -1,5 +1,7 @@
# Can be removed once all rules are addressed or moved to this file as documented overrides
inherit_from: .rubocop_todo.yml inherit_from: .rubocop_todo.yml
# Used for merging with exclude lists with .rubocop_todo.yml
inherit_mode: inherit_mode:
merge: merge:
- Exclude - Exclude
@ -8,32 +10,34 @@ require:
- rubocop-rails - rubocop-rails
- rubocop-rspec - rubocop-rspec
- rubocop-performance - rubocop-performance
- rubocop-capybara
AllCops: AllCops:
TargetRubyVersion: 2.7 TargetRubyVersion: 3.0 # Set to minimum supported version of CI
DisplayCopNames: true DisplayCopNames: true
DisplayStyleGuide: true DisplayStyleGuide: true
ExtraDetails: true ExtraDetails: true
UseCache: true UseCache: true
CacheRootDirectory: tmp CacheRootDirectory: tmp
NewCops: enable NewCops: enable # Opt-in to newly added rules
Exclude: Exclude:
- db/schema.rb - db/schema.rb
- 'app/views/**/*'
- 'config/**/*'
- 'bin/*' - 'bin/*'
- 'Rakefile' - 'Rakefile'
- 'node_modules/**/*' - 'node_modules/**/*'
- 'Vagrantfile' - 'Vagrantfile'
- 'vendor/**/*' - 'vendor/**/*'
- 'lib/json_ld/*' - 'lib/json_ld/*' # Generated files
- 'lib/templates/**/*' - 'lib/templates/**/*'
# Reason: Prefer Hashes without extreme indentation
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation
Layout/FirstHashElementIndentation: Layout/FirstHashElementIndentation:
EnforcedStyle: consistent EnforcedStyle: consistent
# Reason: Currently disabled in .rubocop_todo.yml
# https://docs.rubocop.org/rubocop/cops_layout.html#layoutlinelength
Layout/LineLength: Layout/LineLength:
Max: 140 # RuboCop default 120
AllowedPatterns: AllowedPatterns:
# Allow comments to be long lines # Allow comments to be long lines
- !ruby/regexp / \# .*$/ - !ruby/regexp / \# .*$/
@ -43,83 +47,223 @@ Layout/LineLength:
- db/*migrate/**/* - db/*migrate/**/*
- db/seeds/**/* - db/seeds/**/*
# Reason:
# https://docs.rubocop.org/rubocop/cops_lint.html#lintuselessaccessmodifier
Lint/UselessAccessModifier: Lint/UselessAccessModifier:
ContextCreatingMethods: ContextCreatingMethods:
- class_methods - class_methods
# Reason: Currently disabled in .rubocop_todo.yml
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize
Metrics/AbcSize: Metrics/AbcSize:
Max: 34 # RuboCop default 17
Exclude: Exclude:
- 'lib/**/*cli*.rb' - 'lib/**/*cli*.rb'
- db/*migrate/**/* - db/*migrate/**/*
# Reason: Some functions cannot be broken up, but others may be refactor candidates
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength
Metrics/BlockLength: Metrics/BlockLength:
Max: 55 # Default 25 CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
CountAsOne: [array, heredoc]
Exclude: Exclude:
- 'config/routes.rb'
- 'lib/mastodon/*_cli.rb' - 'lib/mastodon/*_cli.rb'
- 'lib/tasks/*.rake'
- 'app/models/concerns/account_associations.rb'
- 'app/models/concerns/account_interactions.rb'
- 'app/models/concerns/ldap_authenticable.rb'
- 'app/models/concerns/omniauthable.rb'
- 'app/models/concerns/pam_authenticable.rb'
- 'app/models/concerns/remotable.rb'
- 'app/services/suspend_account_service.rb'
- 'app/services/unsuspend_account_service.rb'
- 'app/views/accounts/show.rss.ruby'
- 'app/views/tags/show.rss.ruby'
- 'config/environments/development.rb'
- 'config/environments/production.rb'
- 'config/initializers/devise.rb'
- 'config/initializers/doorkeeper.rb'
- 'config/initializers/omniauth.rb'
- 'config/initializers/simple_form.rb'
- 'config/navigation.rb'
- 'config/routes.rb'
- 'config/routes/*.rb'
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
- 'lib/paperclip/gif_transcoder.rb'
# Reason:
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocknesting
Metrics/BlockNesting: Metrics/BlockNesting:
Exclude: Exclude:
- 'lib/mastodon/*_cli.rb' - 'lib/mastodon/*_cli.rb'
# Reason: Some Excluded files would be candidates for refactoring but not currently addressed
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength
Metrics/ClassLength: Metrics/ClassLength:
Max: 500 # Default 100 CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
CountAsOne: [array, heredoc]
Exclude: Exclude:
- 'lib/mastodon/*_cli.rb' - 'lib/mastodon/*_cli.rb'
- 'app/controllers/admin/accounts_controller.rb'
- 'app/controllers/api/base_controller.rb'
- 'app/controllers/api/v1/admin/accounts_controller.rb'
- 'app/controllers/application_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
- 'app/controllers/auth/sessions_controller.rb'
- 'app/lib/activitypub/activity.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/activitypub/tag_manager.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/link_details_extractor.rb'
- 'app/lib/request.rb'
- 'app/lib/text_formatter.rb'
- 'app/lib/user_settings_decorator.rb'
- 'app/mailers/user_mailer.rb'
- 'app/models/account.rb'
- 'app/models/admin/account_action.rb'
- 'app/models/form/account_batch.rb'
- 'app/models/media_attachment.rb'
- 'app/models/status.rb'
- 'app/models/tag.rb'
- 'app/models/user.rb'
- 'app/serializers/activitypub/actor_serializer.rb'
- 'app/serializers/activitypub/note_serializer.rb'
- 'app/serializers/rest/status_serializer.rb'
- 'app/services/account_search_service.rb'
- 'app/services/activitypub/process_account_service.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/backup_service.rb'
- 'app/services/bulk_import_service.rb'
- 'app/services/delete_account_service.rb'
- 'app/services/fan_out_on_write_service.rb'
- 'app/services/fetch_link_card_service.rb'
- 'app/services/import_service.rb'
- 'app/services/notify_service.rb'
- 'app/services/post_status_service.rb'
- 'app/services/update_status_service.rb'
- 'lib/paperclip/color_extractor.rb'
# Reason: Currently disabled in .rubocop_todo.yml
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity
Metrics/CyclomaticComplexity: Metrics/CyclomaticComplexity:
Max: 12 # Default 7
Exclude: Exclude:
- lib/mastodon/*cli*.rb - lib/mastodon/*cli*.rb
- db/*migrate/**/* - db/*migrate/**/*
# Reason: Currently disabled in .rubocop_todo.yml
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength
Metrics/MethodLength: Metrics/MethodLength:
Max: 25 # RuboCop default 10
CountAsOne: [array, heredoc] CountAsOne: [array, heredoc]
Exclude: Exclude:
- 'lib/mastodon/*_cli.rb' - 'lib/mastodon/*_cli.rb'
# Reason:
# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength
Metrics/ModuleLength: Metrics/ModuleLength:
Max: 200 # Default 100
CountAsOne: [array, heredoc] CountAsOne: [array, heredoc]
Metrics/PerceivedComplexity: # Reason: Prevailing style is argument file paths
Max: 16 # RuboCop default 8 # https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath
Rails/FilePath:
EnforcedStyle: arguments
# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
Rails/HttpStatus: Rails/HttpStatus:
EnforcedStyle: numeric EnforcedStyle: numeric
# Reason: Allowed only in the `tootctl` CLI application code
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
Rails/Exit: Rails/Exit:
Exclude: Exclude:
- 'lib/mastodon/*_cli.rb' - 'lib/mastodon/*_cli.rb'
- 'lib/mastodon/cli_helper.rb' - 'lib/mastodon/cli_helper.rb'
- 'lib/cli.rb' - 'lib/cli.rb'
# Reason: Some single letter camel case files shouldn't be split
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
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
- 'spec/controllers/concerns/account_controller_concern_spec.rb' # Concerns describe ApplicationController and don't fit naming
- 'spec/controllers/concerns/export_controller_concern_spec.rb'
- 'spec/controllers/concerns/localized_spec.rb'
- 'spec/controllers/concerns/rate_limit_headers_spec.rb'
- 'spec/controllers/concerns/signature_verification_spec.rb'
- 'spec/controllers/concerns/user_tracking_concern_spec.rb'
# Reason:
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject
RSpec/NamedSubject:
EnforcedStyle: named_only
# Reason: Prevailing style choice
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot
RSpec/NotToNot: RSpec/NotToNot:
EnforcedStyle: to_not EnforcedStyle: to_not
# Reason: Prevailing style uses numeric status codes, matches Rails/HttpStatus
# https://docs.rubocop.org/rubocop-rspec/cops_rspec_rails.html#rspecrailshttpstatus
RSpec/Rails/HttpStatus: RSpec/Rails/HttpStatus:
EnforcedStyle: numeric EnforcedStyle: numeric
# Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren
Style/ClassAndModuleChildren:
Enabled: false
# Reason: Classes mostly self-document with their names
# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation
Style/Documentation:
Enabled: false
# Reason: Enforce modern Ruby style
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
Style/HashSyntax: Style/HashSyntax:
EnforcedStyle: ruby19_no_mixed_keys EnforcedStyle: ruby19_no_mixed_keys
# Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals
Style/NumericLiterals: Style/NumericLiterals:
AllowedPatterns: AllowedPatterns:
- \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability - \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability
# Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters
Style/PercentLiteralDelimiters: Style/PercentLiteralDelimiters:
PreferredDelimiters: PreferredDelimiters:
'%i': '()' '%i': '()'
'%w': '()' '%w': '()'
# Reason: Prefer less indentation in conditional assignments
# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin
Style/RedundantBegin:
Enabled: false
# Reason: Overridden to reduce implicit StandardError rescues
# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror
Style/RescueStandardError: Style/RescueStandardError:
EnforcedStyle: implicit EnforcedStyle: implicit
# Reason: Originally disabled for CodeClimate, and no config consensus has been found
# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray
Style/SymbolArray:
Enabled: false
# Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral
Style/TrailingCommaInArrayLiteral: Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: 'comma' EnforcedStyleForMultiline: 'comma'
# Reason:
# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral
Style/TrailingCommaInHashLiteral: Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: 'comma' EnforcedStyleForMultiline: 'comma'

File diff suppressed because it is too large Load diff

View file

@ -1 +1 @@
3.2.1 3.2.2

View file

@ -44,3 +44,6 @@ 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

View file

@ -1,4 +1,5 @@
ffmpeg ffmpeg
libopenblas0-pthread
libpq-dev libpq-dev
libxdamage1 libxdamage1
libxfixes3 libxfixes3

View file

@ -2,6 +2,71 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [4.1.2] - 2023-04-04
### Fixed
- Fix crash in `tootctl` commands making use of parallelization when Elasticsearch is enabled ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24182), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24377))
- Fix crash in `db:setup` when Elasticsearch is enabled ([rrgeorge](https://github.com/mastodon/mastodon/pull/24302))
- Fix user archive takeout when using OpenStack Swift or S3 providers with no ACL support ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24200))
- Fix invalid/expired invites being processed on sign-up ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24337))
### Security
- Update Ruby to 3.0.6 due to ReDoS vulnerabilities ([saizai](https://github.com/mastodon/mastodon/pull/24334))
- Fix unescaped user input in LDAP query ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24379))
## [4.1.1] - 2023-03-16
### Added
- Add redirection from paths with url-encoded `@` to their decoded form ([thijskh](https://github.com/mastodon/mastodon/pull/23593))
- Add `lang` attribute to native language names in language picker in Web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23749))
- Add headers to outgoing mails to avoid auto-replies ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23597))
- Add support for refreshing many accounts at once with `tootctl accounts refresh` ([9p4](https://github.com/mastodon/mastodon/pull/23304))
- Add confirmation modal when clicking to edit a post with a non-empty compose form ([PauloVilarinho](https://github.com/mastodon/mastodon/pull/23936))
- Add support for the HAproxy PROXY protocol through the `PROXY_PROTO_V1` environment variable ([CSDUMMI](https://github.com/mastodon/mastodon/pull/24064))
- Add `SENDFILE_HEADER` environment variable ([Gargron](https://github.com/mastodon/mastodon/pull/24123))
- Add cache headers to static files served through Rails ([Gargron](https://github.com/mastodon/mastodon/pull/24120))
### Changed
- Increase contrast of upload progress bar background ([toolmantim](https://github.com/mastodon/mastodon/pull/23836))
- Change post auto-deletion throttling constants to better scale with server size ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23320))
- Change order of bookmark and favourite sidebar entries in single-column UI for consistency ([TerryGarcia](https://github.com/mastodon/mastodon/pull/23701))
- Change `ActivityPub::DeliveryWorker` retries to be spread out more ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21956))
### Fixed
- Fix “Remove all followers from the selected domains” also removing follows and notifications ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23805))
- Fix streaming metrics format ([emilweth](https://github.com/mastodon/mastodon/pull/23519), [emilweth](https://github.com/mastodon/mastodon/pull/23520))
- Fix case-sensitive check for previously used hashtags in hashtag autocompletion ([deanveloper](https://github.com/mastodon/mastodon/pull/23526))
- Fix focus point of already-attached media not saving after edit ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23566))
- Fix sidebar behavior in settings/admin UI on mobile ([wxt2005](https://github.com/mastodon/mastodon/pull/23764))
- Fix inefficiency when searching accounts per username in admin interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23801))
- Fix duplicate “Publish” button on mobile ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23804))
- Fix server error when failing to follow back followers from `/relationships` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23787))
- Fix server error when attempting to display the edit history of a trendable post in the admin interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23574))
- Fix `tootctl accounts migrate` crashing because of a typo ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23567))
- Fix original account being unfollowed on migration before the follow request to the new account could be sent ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21957))
- Fix the “Back” button in column headers sometimes leaving Mastodon ([c960657](https://github.com/mastodon/mastodon/pull/23953))
- Fix pgBouncer resetting application name on every transaction ([Gargron](https://github.com/mastodon/mastodon/pull/23958))
- Fix unconfirmed accounts being counted as active users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23803))
- Fix `/api/v1/streaming` sub-paths not being redirected ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23988))
- Fix drag'n'drop upload area text that spans multiple lines not being centered ([vintprox](https://github.com/mastodon/mastodon/pull/24029))
- Fix sidekiq jobs not triggering Elasticsearch index updates ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24046))
- Fix tags being unnecessarily stripped from plain-text short site description ([c960657](https://github.com/mastodon/mastodon/pull/23975))
- Fix HTML entities not being un-escaped in extracted plain-text from remote posts ([c960657](https://github.com/mastodon/mastodon/pull/24019))
- Fix dashboard crash on ElasticSearch server error ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23751))
- Fix incorrect post links in strikes when the account is remote ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23611))
- Fix misleading error code when receiving invalid WebAuthn credentials ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23568))
- Fix duplicate mails being sent when the SMTP server is too slow to close the connection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23750))
### Security
- Change user backups to use expiring URLs for download when possible ([Gargron](https://github.com/mastodon/mastodon/pull/24136))
- Add warning for object storage misconfiguration ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24137))
## [4.1.0] - 2023-02-10 ## [4.1.0] - 2023-02-10
### Added ### Added

View file

@ -1,4 +1,4 @@
# Contributing to Mastodon Glitch Edition # # Contributing to Mastodon Glitch Edition
Thank you for your interest in contributing to the `glitch-soc` project! Thank you for your interest in contributing to the `glitch-soc` project!
Here are some guidelines, and ways you can help. Here are some guidelines, and ways you can help.
@ -12,26 +12,26 @@ You can submit glitch-soc-specific translations via [Crowdin](https://crowdin.co
[![Crowdin](https://badges.crowdin.net/glitch-soc/localized.svg)](https://crowdin.com/project/glitch-soc) [![Crowdin](https://badges.crowdin.net/glitch-soc/localized.svg)](https://crowdin.com/project/glitch-soc)
## Planning ## ## Planning
Right now a lot of the planning for this project takes place in our development Discord, or through GitHub Issues and Projects. Right now a lot of the planning for this project takes place in our development Discord, or through GitHub Issues and Projects.
We're working on ways to improve the planning structure and better solicit feedback, and if you feel like you can help in this respect, feel free to give us a holler. We're working on ways to improve the planning structure and better solicit feedback, and if you feel like you can help in this respect, feel free to give us a holler.
## Documentation ## ## Documentation
The documentation for this repository is available at [`glitch-soc/docs`](https://github.com/glitch-soc/docs) (online at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/)). The documentation for this repository is available at [`glitch-soc/docs`](https://github.com/glitch-soc/docs) (online at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/)).
Right now, we've mostly focused on the features that make this fork different from upstream in some manner. Right now, we've mostly focused on the features that make this fork different from upstream in some manner.
Adding screenshots, improving descriptions, and so forth are all ways to help contribute to the project even if you don't know any code. Adding screenshots, improving descriptions, and so forth are all ways to help contribute to the project even if you don't know any code.
## Frontend Development ## ## Frontend Development
Check out [the documentation here](https://glitch-soc.github.io/docs/contributing/frontend/) for more information. Check out [the documentation here](https://glitch-soc.github.io/docs/contributing/frontend/) for more information.
## Backend Development ## ## Backend Development
See the guidelines below. See the guidelines below.
- - - ---
You should also try to follow the guidelines set out in the original `CONTRIBUTING.md` from `mastodon/mastodon`, reproduced below. You should also try to follow the guidelines set out in the original `CONTRIBUTING.md` from `mastodon/mastodon`, reproduced below.
@ -80,8 +80,6 @@ It is not always possible to phrase every change in such a manner, but it is des
- Code style rules (rubocop, eslint) - Code style rules (rubocop, eslint)
- Normalization of locale files (i18n-tasks) - Normalization of locale files (i18n-tasks)
**Note**: You may need to log in and authorise the GitHub account your fork of this repository belongs to with CircleCI to enable some of the automated checks to run.
## 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/documentation](https://github.com/mastodon/documentation).

View file

@ -1,8 +1,8 @@
# syntax=docker/dockerfile:1.4 # syntax=docker/dockerfile:1.4
# This needs to be bullseye-slim because the Ruby image is built on bullseye-slim # This needs to be bullseye-slim because the Ruby image is built on bullseye-slim
ARG NODE_VERSION="16.19-bullseye-slim" ARG NODE_VERSION="16.20-bullseye-slim"
FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.1-slim as ruby FROM ghcr.io/moritzheiber/ruby-jemalloc:3.2.2-slim as ruby
FROM node:${NODE_VERSION} as build FROM node:${NODE_VERSION} as build
COPY --link --from=ruby /opt/ruby /opt/ruby COPY --link --from=ruby /opt/ruby /opt/ruby
@ -18,7 +18,6 @@ COPY Gemfile* package.json yarn.lock /opt/mastodon/
# hadolint ignore=DL3008 # hadolint ignore=DL3008
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends build-essential \ apt-get install -y --no-install-recommends build-essential \
ca-certificates \
git \ git \
libicu-dev \ libicu-dev \
libidn11-dev \ libidn11-dev \
@ -37,11 +36,15 @@ RUN apt-get update && \
bundle config set --local without 'development test' && \ bundle config set --local without 'development test' && \
bundle config set silence_root_warning true && \ bundle config set silence_root_warning true && \
bundle install -j"$(nproc)" && \ bundle install -j"$(nproc)" && \
yarn install --pure-lockfile --network-timeout 600000 && \ yarn install --pure-lockfile --production --network-timeout 600000 && \
yarn cache clean yarn cache clean
FROM node:${NODE_VERSION} FROM node:${NODE_VERSION}
# Use those args to specify your own version flags & suffixes
ARG MASTODON_VERSION_FLAGS=""
ARG MASTODON_VERSION_SUFFIX=""
ARG UID="991" ARG UID="991"
ARG GID="991" ARG GID="991"
@ -52,7 +55,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ENV DEBIAN_FRONTEND="noninteractive" \ ENV DEBIAN_FRONTEND="noninteractive" \
PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin"
# Ignoreing these here since we don't want to pin any versions and the Debian image removes apt-get content after use # Ignoring these here since we don't want to pin any versions and the Debian image removes apt-get content after use
# hadolint ignore=DL3008,DL3009 # hadolint ignore=DL3008,DL3009
RUN apt-get update && \ RUN apt-get update && \
echo "Etc/UTC" > /etc/localtime && \ echo "Etc/UTC" > /etc/localtime && \
@ -85,7 +88,9 @@ COPY --chown=mastodon:mastodon --from=build /opt/mastodon /opt/mastodon
ENV RAILS_ENV="production" \ ENV RAILS_ENV="production" \
NODE_ENV="production" \ NODE_ENV="production" \
RAILS_SERVE_STATIC_FILES="true" \ RAILS_SERVE_STATIC_FILES="true" \
BIND="0.0.0.0" BIND="0.0.0.0" \
MASTODON_VERSION_FLAGS="${MASTODON_VERSION_FLAGS}" \
MASTODON_VERSION_SUFFIX="${MASTODON_VERSION_SUFFIX}"
# Set the run user # Set the run user
USER mastodon USER mastodon

120
Gemfile
View file

@ -1,24 +1,23 @@
# frozen_string_literal: true # frozen_string_literal: true
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '>= 2.7.0', '< 3.3.0' ruby '>= 3.0.0'
gem 'pkg-config', '~> 1.5' gem 'pkg-config', '~> 1.5'
gem 'rexml', '~> 3.2'
gem 'puma', '~> 5.6' gem 'puma', '~> 6.2'
gem 'rails', '~> 6.1.7' gem 'rails', '~> 6.1.7'
gem 'sprockets', '~> 3.7.2' gem 'sprockets', '~> 3.7.2'
gem 'thor', '~> 1.2' gem 'thor', '~> 1.2'
gem 'rack', '~> 2.2.6' gem 'rack', '~> 2.2.7'
gem 'haml-rails', '~>2.0' gem 'haml-rails', '~>2.0'
gem 'pg', '~> 1.4' gem 'pg', '~> 1.5'
gem 'makara', '~> 0.5' gem 'makara', '~> 0.5'
gem 'pghero' gem 'pghero'
gem 'dotenv-rails', '~> 2.8' gem 'dotenv-rails', '~> 2.8'
gem 'aws-sdk-s3', '~> 1.119', require: false gem 'aws-sdk-s3', '~> 1.122', require: false
gem 'fog-core', '<= 2.4.0' gem 'fog-core', '<= 2.4.0'
gem 'fog-openstack', '~> 0.3', require: false gem 'fog-openstack', '~> 0.3', require: false
gem 'kt-paperclip', '~> 7.1', github: 'kreeti/kt-paperclip', ref: '11abf222dc31bff71160a1d138b445214f434b2b' gem 'kt-paperclip', '~> 7.1', github: 'kreeti/kt-paperclip', ref: '11abf222dc31bff71160a1d138b445214f434b2b'
@ -29,18 +28,18 @@ gem 'addressable', '~> 2.8'
gem 'bootsnap', '~> 1.16.0', require: false gem 'bootsnap', '~> 1.16.0', require: false
gem 'browser' gem 'browser'
gem 'charlock_holmes', '~> 0.7.7' gem 'charlock_holmes', '~> 0.7.7'
gem 'chewy', '~> 7.2' gem 'chewy', '~> 7.3'
gem 'devise', '~> 4.9' gem 'devise', '~> 4.9'
gem 'devise-two-factor', '~> 4.0' gem 'devise-two-factor', '~> 4.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.17' gem 'net-ldap', '~> 0.18'
gem 'omniauth-cas', '~> 2.0' gem 'omniauth-cas', '~> 2.0'
gem 'omniauth-saml', '~> 1.10' gem 'omniauth-saml', '~> 1.10'
gem 'omniauth_openid_connect', '~> 0.6.0' gem 'omniauth_openid_connect', '~> 0.6.1'
gem 'omniauth', '~> 1.9' gem 'omniauth', '~> 1.9'
gem 'omniauth-rails_csrf_protection', '~> 0.1' gem 'omniauth-rails_csrf_protection', '~> 0.1'
@ -70,14 +69,14 @@ gem 'public_suffix', '~> 5.0'
gem 'pundit', '~> 2.3' gem 'pundit', '~> 2.3'
gem 'premailer-rails' gem 'premailer-rails'
gem 'rack-attack', '~> 6.6' gem 'rack-attack', '~> 6.6'
gem 'rack-cors', '~> 1.1', require: 'rack/cors' gem 'rack-cors', '~> 2.0', require: 'rack/cors'
gem 'rails-i18n', '~> 6.0' gem 'rails-i18n', '~> 6.0'
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', git: 'https://github.com/mastodon/rails-settings-cached.git', branch: 'v0.6.6-aliases-true'
gem 'redcarpet', '~> 3.6' gem 'redcarpet', '~> 3.6'
gem 'redis', '~> 4.5', 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.1' gem 'rqrcode', '~> 2.2'
gem 'ruby-progressbar', '~> 1.11' gem 'ruby-progressbar', '~> 1.13'
gem 'sanitize', '~> 6.0' gem 'sanitize', '~> 6.0'
gem 'scenic', '~> 1.7' gem 'scenic', '~> 1.7'
gem 'sidekiq', '~> 6.5' gem 'sidekiq', '~> 6.5'
@ -88,10 +87,10 @@ gem 'simple-navigation', '~> 4.4'
gem 'simple_form', '~> 5.2' gem 'simple_form', '~> 5.2'
gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie' gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
gem 'stoplight', '~> 3.0.1' gem 'stoplight', '~> 3.0.1'
gem 'strong_migrations', '~> 0.7' gem 'strong_migrations', '~> 0.8'
gem 'tty-prompt', '~> 0.23', require: false gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0' gem 'twitter-text', '~> 3.1.0'
gem 'tzinfo-data', '~> 1.2022' gem 'tzinfo-data', '~> 1.2023'
gem 'webpacker', '~> 5.4' gem 'webpacker', '~> 5.4'
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
gem 'webauthn', '~> 3.0' gem 'webauthn', '~> 3.0'
@ -100,54 +99,87 @@ gem 'json-ld'
gem 'json-ld-preloaded', '~> 3.2' gem 'json-ld-preloaded', '~> 3.2'
gem 'rdf-normalize', '~> 0.5' gem 'rdf-normalize', '~> 0.5'
group :development, :test do gem 'private_address_check', '~> 0.5'
gem 'fabrication', '~> 2.30'
gem 'fuubar', '~> 2.5'
gem 'i18n-tasks', '~> 1.0', require: false
gem 'pry-byebug', '~> 3.10'
gem 'pry-rails', '~> 0.3'
gem 'rspec-rails', '~> 5.1'
gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
gem 'rubocop', require: false
end
group :production, :test do
gem 'private_address_check', '~> 0.5'
end
group :test do group :test do
gem 'capybara', '~> 3.38' # RSpec runner for rails
gem 'climate_control', '~> 0.2' gem 'rspec-rails', '~> 6.0'
gem 'faker', '~> 3.1'
gem 'json-schema', '~> 3.0' # Used to split testing into chunks in CI
gem 'rack-test', '~> 2.0' gem 'rspec_chunked', '~> 0.6'
gem 'rails-controller-testing', '~> 1.0'
gem 'rspec_junit_formatter', '~> 0.6' # RSpec progress bar formatter
gem 'fuubar', '~> 2.5'
# Extra RSpec extenion methods and helpers for sidekiq
gem 'rspec-sidekiq', '~> 3.1' gem 'rspec-sidekiq', '~> 3.1'
# Browser integration testing
gem 'capybara', '~> 3.39'
# Used to mock environment variables
gem 'climate_control', '~> 0.2'
# Generating fake data for specs
gem 'faker', '~> 3.2'
# Generate test objects for specs
gem 'fabrication', '~> 2.30'
# Add back helpers functions removed in Rails 5.1
gem 'rails-controller-testing', '~> 1.0'
# Validate schemas in specs
gem 'json-schema', '~> 4.0'
# Test harness fo rack components
gem 'rack-test', '~> 2.1'
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
gem 'simplecov', '~> 0.22', require: false gem 'simplecov', '~> 0.22', require: false
# Stub web requests for specs
gem 'webmock', '~> 3.18' gem 'webmock', '~> 3.18'
end end
group :development do group :development do
gem 'active_record_query_trace', '~> 1.8' # Code linting CLI and plugins
gem 'rubocop', require: false
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' 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', '~> 1.0'
gem 'bullet', '~> 7.0'
# Preview mail in the browser
gem 'letter_opener', '~> 1.8' gem 'letter_opener', '~> 1.8'
gem 'letter_opener_web', '~> 2.0' gem 'letter_opener_web', '~> 2.0'
gem 'memory_profiler'
# Security analysis CLI tools
gem 'brakeman', '~> 5.4', require: false gem 'brakeman', '~> 5.4', require: false
gem 'bundler-audit', '~> 0.9', 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', '~> 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'
gem 'stackprof' # Validate missing i18n keys
gem 'i18n-tasks', '~> 1.0', require: false
# Profiling tools
gem 'memory_profiler', require: false
gem 'stackprof', require: false
end end
group :production do group :production do
@ -158,7 +190,9 @@ gem 'concurrent-ruby', require: false
gem 'connection_pool', require: false gem 'connection_pool', require: false
gem 'xorcist', '~> 1.1' gem 'xorcist', '~> 1.1'
gem 'hcaptcha', '~> 7.1'
gem 'cocoon', '~> 1.2' gem 'cocoon', '~> 1.2'
gem 'net-http', '~> 0.3.2' gem 'net-http', '~> 0.3.2'
gem 'rubyzip', '~> 2.3'
gem 'hcaptcha', '~> 7.1'

View file

@ -30,40 +30,40 @@ GIT
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
actioncable (6.1.7.2) actioncable (6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
nio4r (~> 2.0) nio4r (~> 2.0)
websocket-driver (>= 0.6.1) websocket-driver (>= 0.6.1)
actionmailbox (6.1.7.2) actionmailbox (6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
activejob (= 6.1.7.2) activejob (= 6.1.7.3)
activerecord (= 6.1.7.2) activerecord (= 6.1.7.3)
activestorage (= 6.1.7.2) activestorage (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
mail (>= 2.7.1) mail (>= 2.7.1)
actionmailer (6.1.7.2) actionmailer (6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
actionview (= 6.1.7.2) actionview (= 6.1.7.3)
activejob (= 6.1.7.2) activejob (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (6.1.7.2) actionpack (6.1.7.3)
actionview (= 6.1.7.2) actionview (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
rack (~> 2.0, >= 2.0.9) rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.1.7.2) actiontext (6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
activerecord (= 6.1.7.2) activerecord (= 6.1.7.3)
activestorage (= 6.1.7.2) activestorage (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
nokogiri (>= 1.8.5) nokogiri (>= 1.8.5)
actionview (6.1.7.2) actionview (6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
builder (~> 3.1) builder (~> 3.1)
erubi (~> 1.4) erubi (~> 1.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
@ -73,29 +73,28 @@ GEM
activemodel (>= 4.1, < 7.1) activemodel (>= 4.1, < 7.1)
case_transform (>= 0.2) case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3) jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
active_record_query_trace (1.8) activejob (6.1.7.3)
activejob (6.1.7.2) activesupport (= 6.1.7.3)
activesupport (= 6.1.7.2)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (6.1.7.2) activemodel (6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
activerecord (6.1.7.2) activerecord (6.1.7.3)
activemodel (= 6.1.7.2) activemodel (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
activestorage (6.1.7.2) activestorage (6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
activejob (= 6.1.7.2) activejob (= 6.1.7.3)
activerecord (= 6.1.7.2) activerecord (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
marcel (~> 1.0) marcel (~> 1.0)
mini_mime (>= 1.1.0) mini_mime (>= 1.1.0)
activesupport (6.1.7.2) activesupport (6.1.7.3)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2) i18n (>= 1.6, < 2)
minitest (>= 5.1) minitest (>= 5.1)
tzinfo (~> 2.0) tzinfo (~> 2.0)
zeitwerk (~> 2.3) zeitwerk (~> 2.3)
addressable (2.8.1) addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0) public_suffix (>= 2.0.2, < 6.0)
aes_key_wrap (1.1.0) aes_key_wrap (1.1.0)
airbrussh (1.4.1) airbrussh (1.4.1)
@ -105,21 +104,21 @@ GEM
activerecord (>= 3.2, < 8.0) activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0) rake (>= 10.4, < 14.0)
ast (2.4.2) ast (2.4.2)
attr_encrypted (3.1.0) attr_encrypted (4.0.0)
encryptor (~> 3.0.0) encryptor (~> 3.0.0)
attr_required (1.0.1) attr_required (1.0.1)
awrence (1.2.1) awrence (1.2.1)
aws-eventstream (1.2.0) aws-eventstream (1.2.0)
aws-partitions (1.711.0) aws-partitions (1.761.0)
aws-sdk-core (3.170.0) aws-sdk-core (3.172.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0) aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5) aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.62.0) aws-sdk-kms (1.64.0)
aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.119.1) aws-sdk-s3 (1.122.0)
aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4) aws-sigv4 (~> 1.4)
@ -143,25 +142,21 @@ GEM
blurhash (0.1.7) blurhash (0.1.7)
bootsnap (1.16.0) bootsnap (1.16.0)
msgpack (~> 1.2) msgpack (~> 1.2)
brakeman (5.4.0) brakeman (5.4.1)
browser (4.2.0) browser (5.3.1)
brpoplpush-redis_script (0.1.3) brpoplpush-redis_script (0.1.3)
concurrent-ruby (~> 1.0, >= 1.0.5) concurrent-ruby (~> 1.0, >= 1.0.5)
redis (>= 1.0, < 6) redis (>= 1.0, < 6)
builder (3.2.4) builder (3.2.4)
bullet (7.0.7)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
bundler-audit (0.9.1) bundler-audit (0.9.1)
bundler (>= 1.2.0, < 3) bundler (>= 1.2.0, < 3)
thor (~> 1.0) thor (~> 1.0)
byebug (11.1.3)
capistrano (3.17.2) capistrano (3.17.2)
airbrussh (>= 1.0.0) airbrussh (>= 1.0.0)
i18n i18n
rake (>= 10.0.0) rake (>= 10.0.0)
sshkit (>= 1.9.0) sshkit (>= 1.9.0)
capistrano-bundler (2.0.1) capistrano-bundler (2.1.0)
capistrano (~> 3.1) capistrano (~> 3.1)
capistrano-rails (1.6.2) capistrano-rails (1.6.2)
capistrano (~> 3.1) capistrano (~> 3.1)
@ -171,7 +166,7 @@ GEM
sshkit (~> 1.3) sshkit (~> 1.3)
capistrano-yarn (2.0.2) capistrano-yarn (2.0.2)
capistrano (~> 3.0) capistrano (~> 3.0)
capybara (3.38.0) capybara (3.39.1)
addressable addressable
matrix matrix
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
@ -184,7 +179,7 @@ GEM
activesupport activesupport
cbor (0.5.9.6) cbor (0.5.9.6)
charlock_holmes (0.7.7) charlock_holmes (0.7.7)
chewy (7.2.7) chewy (7.3.2)
activesupport (>= 5.2) activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch (>= 7.12.0, < 7.14.0)
elasticsearch-dsl elasticsearch-dsl
@ -193,27 +188,27 @@ GEM
cocoon (1.2.15) cocoon (1.2.15)
coderay (1.1.3) coderay (1.1.3)
color_diff (0.1) color_diff (0.1)
concurrent-ruby (1.2.0) concurrent-ruby (1.2.2)
connection_pool (2.3.0) connection_pool (2.4.1)
cose (1.3.0) cose (1.3.0)
cbor (~> 0.5.9) cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0) openssl-signature_algorithm (~> 1.0)
crack (0.4.5) crack (0.4.5)
rexml rexml
crass (1.0.6) crass (1.0.6)
css_parser (1.12.0) css_parser (1.14.0)
addressable addressable
date (3.3.3) date (3.3.3)
debug_inspector (1.0.0) debug_inspector (1.1.0)
devise (4.9.0) devise (4.9.2)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 4.1.0) railties (>= 4.1.0)
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
devise-two-factor (4.0.2) devise-two-factor (4.1.0)
activesupport (< 7.1) activesupport (< 7.1)
attr_encrypted (>= 1.3, < 4, != 2) attr_encrypted (>= 1.3, < 5, != 2)
devise (~> 4.0) devise (~> 4.0)
railties (< 7.1) railties (< 7.1)
rotp (~> 6.0) rotp (~> 6.0)
@ -226,7 +221,7 @@ GEM
docile (1.4.0) docile (1.4.0)
domain_name (0.5.20190701) domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.6.4) doorkeeper (5.6.6)
railties (>= 5) railties (>= 5)
dotenv (2.8.1) dotenv (2.8.1)
dotenv-rails (2.8.1) dotenv-rails (2.8.1)
@ -246,9 +241,9 @@ GEM
erubi (1.12.0) erubi (1.12.0)
et-orbi (1.2.7) et-orbi (1.2.7)
tzinfo tzinfo
excon (0.95.0) excon (0.99.0)
fabrication (2.30.0) fabrication (2.30.0)
faker (3.1.1) faker (3.2.0)
i18n (>= 1.8.11, < 2) i18n (>= 1.8.11, < 2)
faraday (1.10.3) faraday (1.10.3)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
@ -309,11 +304,17 @@ GEM
activesupport (>= 5.1) activesupport (>= 5.1)
haml (>= 4.0.6) haml (>= 4.0.6)
railties (>= 5.1) railties (>= 5.1)
haml_lint (0.45.0)
haml (>= 4.0, < 6.2)
parallel (~> 1.10)
rainbow
rubocop (>= 0.50.0)
sysexits (~> 1.1)
hashdiff (1.0.1) hashdiff (1.0.1)
hashie (5.0.0) hashie (5.0.0)
hcaptcha (7.1.0) hcaptcha (7.1.0)
json json
highline (2.0.3) highline (2.1.0)
hiredis (0.6.3) hiredis (0.6.3)
hkdf (0.3.0) hkdf (0.3.0)
htmlentities (4.3.4) htmlentities (4.3.4)
@ -330,7 +331,7 @@ GEM
httplog (1.6.2) httplog (1.6.2)
rack (>= 2.0) rack (>= 2.0)
rainbow (>= 2.0.0) rainbow (>= 2.0.0)
i18n (1.12.0) i18n (1.13.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n-tasks (1.0.12) i18n-tasks (1.0.12)
activesupport (>= 4.0.2) activesupport (>= 4.0.2)
@ -347,23 +348,23 @@ GEM
ipaddress (0.8.3) ipaddress (0.8.3)
jmespath (1.6.2) jmespath (1.6.2)
json (2.6.3) json (2.6.3)
json-canonicalization (0.3.0) json-canonicalization (0.3.2)
json-jwt (1.15.3) json-jwt (1.15.3)
activesupport (>= 4.2) activesupport (>= 4.2)
aes_key_wrap aes_key_wrap
bindata bindata
httpclient httpclient
json-ld (3.2.3) json-ld (3.2.5)
htmlentities (~> 4.3) htmlentities (~> 4.3)
json-canonicalization (~> 0.3) json-canonicalization (~> 0.3, >= 0.3.2)
link_header (~> 0.0, >= 0.0.8) link_header (~> 0.0, >= 0.0.8)
multi_json (~> 1.15) multi_json (~> 1.15)
rack (~> 2.2) rack (>= 2.2, < 4)
rdf (~> 3.2, >= 3.2.9) rdf (~> 3.2, >= 3.2.10)
json-ld-preloaded (3.2.2) json-ld-preloaded (3.2.2)
json-ld (~> 3.2) json-ld (~> 3.2)
rdf (~> 3.2) rdf (~> 3.2)
json-schema (3.0.0) json-schema (4.0.0)
addressable (>= 2.8) addressable (>= 2.8)
jsonapi-renderer (0.2.2) jsonapi-renderer (0.2.2)
jwt (2.7.0) jwt (2.7.0)
@ -379,8 +380,8 @@ GEM
activerecord activerecord
kaminari-core (= 1.2.2) kaminari-core (= 1.2.2)
kaminari-core (1.2.2) kaminari-core (1.2.2)
launchy (2.5.0) launchy (2.5.2)
addressable (~> 2.7) addressable (~> 2.8)
letter_opener (1.8.1) letter_opener (1.8.1)
launchy (>= 2.2, < 3) launchy (>= 2.2, < 3)
letter_opener_web (2.0.0) letter_opener_web (2.0.0)
@ -397,10 +398,10 @@ GEM
activesupport (>= 4) activesupport (>= 4)
railties (>= 4) railties (>= 4)
request_store (~> 1.0) request_store (~> 1.0)
loofah (2.19.1) loofah (2.21.3)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.5.9) nokogiri (>= 1.12.0)
mail (2.8.0.1) mail (2.8.1)
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
net-imap net-imap
net-pop net-pop
@ -415,11 +416,11 @@ GEM
method_source (1.0.0) method_source (1.0.0)
mime-types (3.4.1) mime-types (3.4.1)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2022.0105) mime-types-data (3.2023.0218.1)
mini_mime (1.1.2) mini_mime (1.1.2)
mini_portile2 (2.8.1) mini_portile2 (2.8.2)
minitest (5.17.0) minitest (5.18.0)
msgpack (1.6.0) msgpack (1.7.0)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.3.0) multipart-post (2.3.0)
net-http (0.3.2) net-http (0.3.2)
@ -427,7 +428,7 @@ GEM
net-imap (0.3.4) net-imap (0.3.4)
date date
net-protocol net-protocol
net-ldap (0.17.1) net-ldap (0.18.0)
net-pop (0.1.2) net-pop (0.1.2)
net-protocol net-protocol
net-protocol (0.2.1) net-protocol (0.2.1)
@ -436,9 +437,9 @@ GEM
net-ssh (>= 2.6.5, < 8.0.0) net-ssh (>= 2.6.5, < 8.0.0)
net-smtp (0.3.3) net-smtp (0.3.3)
net-protocol net-protocol
net-ssh (7.0.1) net-ssh (7.1.0)
nio4r (2.5.8) nio4r (2.5.9)
nokogiri (1.14.2) nokogiri (1.14.3)
mini_portile2 (~> 2.8.0) mini_portile2 (~> 2.8.0)
racc (~> 1.4) racc (~> 1.4)
nsa (0.2.8) nsa (0.2.8)
@ -446,7 +447,7 @@ GEM
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5) sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0) statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.14.2) oj (3.14.3)
omniauth (1.9.2) omniauth (1.9.2)
hashie (>= 3.4.6) hashie (>= 3.4.6)
rack (>= 1.6.2, < 3) rack (>= 1.6.2, < 3)
@ -460,7 +461,7 @@ GEM
omniauth-saml (1.10.3) omniauth-saml (1.10.3)
omniauth (~> 1.3, >= 1.3.2) omniauth (~> 1.3, >= 1.3.2)
ruby-saml (~> 1.9) ruby-saml (~> 1.9)
omniauth_openid_connect (0.6.0) omniauth_openid_connect (0.6.1)
omniauth (>= 1.9, < 3) omniauth (>= 1.9, < 3)
openid_connect (~> 1.1) openid_connect (~> 1.1)
openid_connect (1.4.2) openid_connect (1.4.2)
@ -478,19 +479,19 @@ GEM
openssl-signature_algorithm (1.3.0) openssl-signature_algorithm (1.3.0)
openssl (> 2.0) openssl (> 2.0)
orm_adapter (0.5.0) orm_adapter (0.5.0)
ox (2.14.14) ox (2.14.16)
parallel (1.22.1) parallel (1.23.0)
parser (3.2.1.0) parser (3.2.2.1)
ast (~> 2.4.1) ast (~> 2.4.1)
parslet (2.0.0) parslet (2.0.0)
pastel (0.8.0) pastel (0.8.0)
tty-color (~> 0.5) tty-color (~> 0.5)
pg (1.4.5) pg (1.5.3)
pghero (3.1.0) pghero (3.3.3)
activerecord (>= 6) activerecord (>= 6)
pkg-config (1.5.1) pkg-config (1.5.1)
posix-spawn (0.3.15) posix-spawn (0.3.15)
premailer (1.18.0) premailer (1.21.0)
addressable addressable
css_parser (>= 1.12.0) css_parser (>= 1.12.0)
htmlentities (>= 4.0.0) htmlentities (>= 4.0.0)
@ -499,25 +500,17 @@ GEM
net-smtp net-smtp
premailer (~> 1.7, >= 1.7.9) premailer (~> 1.7, >= 1.7.9)
private_address_check (0.5.0) private_address_check (0.5.0)
pry (0.14.1)
coderay (~> 1.1)
method_source (~> 1.0)
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (5.0.1) public_suffix (5.0.1)
puma (5.6.5) puma (6.2.2)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.3.0) pundit (2.3.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.4.0) raabro (1.4.0)
racc (1.6.2) racc (1.6.2)
rack (2.2.6.2) rack (2.2.7)
rack-attack (6.6.1) rack-attack (6.6.1)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rack-cors (1.1.1) rack-cors (2.0.1)
rack (>= 2.0.0) rack (>= 2.0.0)
rack-oauth2 (1.21.3) rack-oauth2 (1.21.3)
activesupport activesupport
@ -527,22 +520,22 @@ GEM
rack (>= 2.1.0) rack (>= 2.1.0)
rack-proxy (0.7.6) rack-proxy (0.7.6)
rack rack
rack-test (2.0.2) rack-test (2.1.0)
rack (>= 1.3) rack (>= 1.3)
rails (6.1.7.2) rails (6.1.7.3)
actioncable (= 6.1.7.2) actioncable (= 6.1.7.3)
actionmailbox (= 6.1.7.2) actionmailbox (= 6.1.7.3)
actionmailer (= 6.1.7.2) actionmailer (= 6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
actiontext (= 6.1.7.2) actiontext (= 6.1.7.3)
actionview (= 6.1.7.2) actionview (= 6.1.7.3)
activejob (= 6.1.7.2) activejob (= 6.1.7.3)
activemodel (= 6.1.7.2) activemodel (= 6.1.7.3)
activerecord (= 6.1.7.2) activerecord (= 6.1.7.3)
activestorage (= 6.1.7.2) activestorage (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
bundler (>= 1.15.0) bundler (>= 1.15.0)
railties (= 6.1.7.2) railties (= 6.1.7.3)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5) rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1) actionpack (>= 5.0.1.rc1)
@ -556,88 +549,88 @@ GEM
rails-i18n (6.0.0) rails-i18n (6.0.0)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 7) railties (>= 6.0.0, < 7)
railties (6.1.7.2) railties (6.1.7.3)
actionpack (= 6.1.7.2) actionpack (= 6.1.7.3)
activesupport (= 6.1.7.2) activesupport (= 6.1.7.3)
method_source method_source
rake (>= 12.2) rake (>= 12.2)
thor (~> 1.0) thor (~> 1.0)
rainbow (3.1.1) rainbow (3.1.1)
rake (13.0.6) rake (13.0.6)
rdf (3.2.9) rdf (3.2.10)
link_header (~> 0.0, >= 0.0.8) link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.5.1) rdf-normalize (0.5.1)
rdf (~> 3.2) rdf (~> 3.2)
redcarpet (3.6.0) redcarpet (3.6.0)
redis (4.5.1) redis (4.8.1)
redis-namespace (1.10.0) redis-namespace (1.10.0)
redis (>= 4) redis (>= 4)
redlock (1.3.2) redlock (1.3.2)
redis (>= 3.0.0, < 6.0) redis (>= 3.0.0, < 6.0)
regexp_parser (2.7.0) regexp_parser (2.8.0)
request_store (1.5.1) request_store (1.5.1)
rack (>= 1.4) rack (>= 1.4)
responders (3.1.0) responders (3.1.0)
actionpack (>= 5.2) actionpack (>= 5.2)
railties (>= 5.2) railties (>= 5.2)
rexml (3.2.5) rexml (3.2.5)
rotp (6.2.0) rotp (6.2.2)
rpam2 (4.0.2) rpam2 (4.0.2)
rqrcode (2.1.2) rqrcode (2.2.0)
chunky_png (~> 1.0) chunky_png (~> 1.0)
rqrcode_core (~> 1.0) rqrcode_core (~> 1.0)
rqrcode_core (1.2.0) rqrcode_core (1.2.0)
rspec-core (3.11.0) rspec-core (3.12.2)
rspec-support (~> 3.11.0) rspec-support (~> 3.12.0)
rspec-expectations (3.11.0) rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0) rspec-support (~> 3.12.0)
rspec-mocks (3.11.1) rspec-mocks (3.12.5)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0) rspec-support (~> 3.12.0)
rspec-rails (5.1.2) rspec-rails (6.0.2)
actionpack (>= 5.2) actionpack (>= 6.1)
activesupport (>= 5.2) activesupport (>= 6.1)
railties (>= 5.2) railties (>= 6.1)
rspec-core (~> 3.10) rspec-core (~> 3.12)
rspec-expectations (~> 3.10) rspec-expectations (~> 3.12)
rspec-mocks (~> 3.10) rspec-mocks (~> 3.12)
rspec-support (~> 3.10) rspec-support (~> 3.12)
rspec-sidekiq (3.1.0) rspec-sidekiq (3.1.0)
rspec-core (~> 3.0, >= 3.0.0) rspec-core (~> 3.0, >= 3.0.0)
sidekiq (>= 2.4.0) sidekiq (>= 2.4.0)
rspec-support (3.11.1) rspec-support (3.12.0)
rspec_junit_formatter (0.6.0) rspec_chunked (0.6)
rspec-core (>= 2, < 4, != 2.12.0) rubocop (1.51.0)
rubocop (1.45.1)
json (~> 2.3) json (~> 2.3)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.2.0.0) parser (>= 3.2.0.0)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0) regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0) rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.24.1, < 2.0) rubocop-ast (>= 1.28.0, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0) unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.24.1) rubocop-ast (1.28.1)
parser (>= 3.1.1.0) parser (>= 3.2.1.0)
rubocop-capybara (2.17.0) rubocop-capybara (2.18.0)
rubocop (~> 1.41) rubocop (~> 1.41)
rubocop-performance (1.16.0) rubocop-performance (1.18.0)
rubocop (>= 1.7.0, < 2.0) rubocop (>= 1.7.0, < 2.0)
rubocop-ast (>= 0.4.0) rubocop-ast (>= 0.4.0)
rubocop-rails (2.17.4) rubocop-rails (2.19.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0) rubocop (>= 1.33.0, < 2.0)
rubocop-rspec (2.18.1) rubocop-rspec (2.19.0)
rubocop (~> 1.33) rubocop (~> 1.33)
rubocop-capybara (~> 2.17) rubocop-capybara (~> 2.17)
ruby-progressbar (1.11.0) ruby-progressbar (1.13.0)
ruby-saml (1.13.0) ruby-saml (1.13.0)
nokogiri (>= 1.10.5) nokogiri (>= 1.10.5)
rexml rexml
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rufus-scheduler (3.8.2) rufus-scheduler (3.8.2)
fugit (~> 1.1, >= 1.1.6) fugit (~> 1.1, >= 1.1.6)
safety_net_attestation (0.4.0) safety_net_attestation (0.4.0)
@ -655,9 +648,9 @@ GEM
redis (>= 4.5.0, < 5) redis (>= 4.5.0, < 5)
sidekiq-bulk (0.2.0) sidekiq-bulk (0.2.0)
sidekiq sidekiq
sidekiq-scheduler (5.0.1) sidekiq-scheduler (5.0.2)
rufus-scheduler (~> 3.2) rufus-scheduler (~> 3.2)
sidekiq (>= 4, < 8) sidekiq (>= 6, < 8)
tilt (>= 1.4.0) tilt (>= 1.4.0)
sidekiq-unique-jobs (7.1.29) sidekiq-unique-jobs (7.1.29)
brpoplpush-redis_script (> 0.1.1, <= 2.0.0) brpoplpush-redis_script (> 0.1.1, <= 2.0.0)
@ -687,24 +680,25 @@ GEM
sshkit (1.21.4) sshkit (1.21.4)
net-scp (>= 1.1.2) net-scp (>= 1.1.2)
net-ssh (>= 2.8.0) net-ssh (>= 2.8.0)
stackprof (0.2.23) stackprof (0.2.25)
statsd-ruby (1.5.0) statsd-ruby (1.5.0)
stoplight (3.0.1) stoplight (3.0.1)
redlock (~> 1.0) redlock (~> 1.0)
strong_migrations (0.7.9) strong_migrations (0.8.0)
activerecord (>= 5) activerecord (>= 5.2)
swd (1.3.0) swd (1.3.0)
activesupport (>= 3) activesupport (>= 3)
attr_required (>= 0.0.5) attr_required (>= 0.0.5)
httpclient (>= 2.4) httpclient (>= 2.4)
sysexits (1.2.0)
temple (0.10.0) temple (0.10.0)
terminal-table (3.0.2) terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)
terrapin (0.6.0) terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0) climate_control (>= 0.0.3, < 1.0)
thor (1.2.1) thor (1.2.2)
tilt (2.0.11) tilt (2.1.0)
timeout (0.3.1) timeout (0.3.2)
tpm-key_attestation (0.12.0) tpm-key_attestation (0.12.0)
bindata (~> 2.4) bindata (~> 2.4)
openssl (> 2.0) openssl (> 2.0)
@ -724,14 +718,13 @@ GEM
unf (~> 0.1.0) unf (~> 0.1.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
tzinfo-data (1.2022.7) tzinfo-data (1.2023.3)
tzinfo (>= 1.0.0) tzinfo (>= 1.0.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.8.2) unf_ext (0.0.8.2)
unicode-display_width (2.4.2) unicode-display_width (2.4.2)
uniform_notifier (1.16.0) uri (0.12.1)
uri (0.12.0)
validate_email (0.1.6) validate_email (0.1.6)
activemodel (>= 3.0) activemodel (>= 3.0)
mail (>= 2.2.5) mail (>= 2.2.5)
@ -768,52 +761,51 @@ GEM
xorcist (1.1.3) xorcist (1.1.3)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.6.7) zeitwerk (2.6.8)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
active_model_serializers (~> 0.10) active_model_serializers (~> 0.10)
active_record_query_trace (~> 1.8)
addressable (~> 2.8) addressable (~> 2.8)
annotate (~> 3.2) annotate (~> 3.2)
aws-sdk-s3 (~> 1.119) aws-sdk-s3 (~> 1.122)
better_errors (~> 2.9) better_errors (~> 2.9)
binding_of_caller (~> 1.0) binding_of_caller (~> 1.0)
blurhash (~> 0.1) blurhash (~> 0.1)
bootsnap (~> 1.16.0) bootsnap (~> 1.16.0)
brakeman (~> 5.4) brakeman (~> 5.4)
browser browser
bullet (~> 7.0)
bundler-audit (~> 0.9) bundler-audit (~> 0.9)
capistrano (~> 3.17) capistrano (~> 3.17)
capistrano-rails (~> 1.6) capistrano-rails (~> 1.6)
capistrano-rbenv (~> 2.2) capistrano-rbenv (~> 2.2)
capistrano-yarn (~> 2.0) capistrano-yarn (~> 2.0)
capybara (~> 3.38) capybara (~> 3.39)
charlock_holmes (~> 0.7.7) charlock_holmes (~> 0.7.7)
chewy (~> 7.2) chewy (~> 7.3)
climate_control (~> 0.2) climate_control (~> 0.2)
cocoon (~> 1.2) cocoon (~> 1.2)
color_diff (~> 0.1) color_diff (~> 0.1)
concurrent-ruby concurrent-ruby
connection_pool connection_pool
devise (~> 4.9) devise (~> 4.9)
devise-two-factor (~> 4.0) devise-two-factor (~> 4.1)
devise_pam_authenticatable2 (~> 9.2) devise_pam_authenticatable2 (~> 9.2)
discard (~> 1.2) discard (~> 1.2)
doorkeeper (~> 5.6) doorkeeper (~> 5.6)
dotenv-rails (~> 2.8) dotenv-rails (~> 2.8)
ed25519 (~> 1.3) ed25519 (~> 1.3)
fabrication (~> 2.30) fabrication (~> 2.30)
faker (~> 3.1) faker (~> 3.2)
fast_blank (~> 1.0) fast_blank (~> 1.0)
fastimage fastimage
fog-core (<= 2.4.0) fog-core (<= 2.4.0)
fog-openstack (~> 0.3) fog-openstack (~> 0.3)
fuubar (~> 2.5) fuubar (~> 2.5)
haml-rails (~> 2.0) haml-rails (~> 2.0)
haml_lint
hcaptcha (~> 7.1) hcaptcha (~> 7.1)
hiredis (~> 0.6) hiredis (~> 0.6)
htmlentities (~> 4.3) htmlentities (~> 4.3)
@ -824,7 +816,7 @@ DEPENDENCIES
idn-ruby idn-ruby
json-ld json-ld
json-ld-preloaded (~> 3.2) json-ld-preloaded (~> 3.2)
json-schema (~> 3.0) json-schema (~> 4.0)
kaminari (~> 1.2) kaminari (~> 1.2)
kt-paperclip (~> 7.1)! kt-paperclip (~> 7.1)!
letter_opener (~> 1.8) letter_opener (~> 1.8)
@ -836,7 +828,7 @@ DEPENDENCIES
memory_profiler memory_profiler
mime-types (~> 3.4.1) mime-types (~> 3.4.1)
net-http (~> 0.3.2) net-http (~> 0.3.2)
net-ldap (~> 0.17) net-ldap (~> 0.18)
nokogiri (~> 1.14) nokogiri (~> 1.14)
nsa (~> 0.2) nsa (~> 0.2)
oj (~> 3.14) oj (~> 3.14)
@ -844,24 +836,22 @@ DEPENDENCIES
omniauth-cas (~> 2.0) omniauth-cas (~> 2.0)
omniauth-rails_csrf_protection (~> 0.1) omniauth-rails_csrf_protection (~> 0.1)
omniauth-saml (~> 1.10) omniauth-saml (~> 1.10)
omniauth_openid_connect (~> 0.6.0) omniauth_openid_connect (~> 0.6.1)
ox (~> 2.14) ox (~> 2.14)
parslet parslet
pg (~> 1.4) pg (~> 1.5)
pghero pghero
pkg-config (~> 1.5) pkg-config (~> 1.5)
posix-spawn posix-spawn
premailer-rails premailer-rails
private_address_check (~> 0.5) private_address_check (~> 0.5)
pry-byebug (~> 3.10)
pry-rails (~> 0.3)
public_suffix (~> 5.0) public_suffix (~> 5.0)
puma (~> 5.6) puma (~> 6.2)
pundit (~> 2.3) pundit (~> 2.3)
rack (~> 2.2.6) rack (~> 2.2.7)
rack-attack (~> 6.6) rack-attack (~> 6.6)
rack-cors (~> 1.1) rack-cors (~> 2.0)
rack-test (~> 2.0) rack-test (~> 2.1)
rails (~> 6.1.7) rails (~> 6.1.7)
rails-controller-testing (~> 1.0) rails-controller-testing (~> 1.0)
rails-i18n (~> 6.0) rails-i18n (~> 6.0)
@ -870,16 +860,17 @@ DEPENDENCIES
redcarpet (~> 3.6) redcarpet (~> 3.6)
redis (~> 4.5) redis (~> 4.5)
redis-namespace (~> 1.10) redis-namespace (~> 1.10)
rexml (~> 3.2) rqrcode (~> 2.2)
rqrcode (~> 2.1) rspec-rails (~> 6.0)
rspec-rails (~> 5.1)
rspec-sidekiq (~> 3.1) rspec-sidekiq (~> 3.1)
rspec_junit_formatter (~> 0.6) rspec_chunked (~> 0.6)
rubocop rubocop
rubocop-capybara
rubocop-performance rubocop-performance
rubocop-rails rubocop-rails
rubocop-rspec rubocop-rspec
ruby-progressbar (~> 1.11) ruby-progressbar (~> 1.13)
rubyzip (~> 2.3)
sanitize (~> 6.0) sanitize (~> 6.0)
scenic (~> 1.7) scenic (~> 1.7)
sidekiq (~> 6.5) sidekiq (~> 6.5)
@ -893,11 +884,11 @@ DEPENDENCIES
sprockets-rails (~> 3.4) sprockets-rails (~> 3.4)
stackprof stackprof
stoplight (~> 3.0.1) stoplight (~> 3.0.1)
strong_migrations (~> 0.7) strong_migrations (~> 0.8)
thor (~> 1.2) thor (~> 1.2)
tty-prompt (~> 0.23) tty-prompt (~> 0.23)
twitter-text (~> 3.1.0) twitter-text (~> 3.1.0)
tzinfo-data (~> 1.2022) tzinfo-data (~> 1.2023)
webauthn (~> 3.0) webauthn (~> 3.0)
webmock (~> 3.18) webmock (~> 3.18)
webpacker (~> 5.4) webpacker (~> 5.4)

View file

@ -1,6 +1,4 @@
# Mastodon, Queer.af+Glitch Edition #
We're a downstream of [glitch-soc](https://github.com/glitch-soc/mastodon/). You probably want that
## Updating ## Updating
```bash ```bash

View file

@ -8,7 +8,7 @@ class AboutController < ApplicationController
before_action :set_instance_presenter before_action :set_instance_presenter
def show def show
expires_in 0, public: true unless user_signed_in? expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
end end
private private

View file

@ -7,8 +7,9 @@ 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_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? } before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
before_action :set_cache_headers
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: :whitelist_mode? skip_before_action :require_functional!, unless: :whitelist_mode?
@ -16,7 +17,7 @@ class AccountsController < ApplicationController
def show def show
respond_to do |format| respond_to do |format|
format.html do format.html do
expires_in 0, public: true unless user_signed_in? expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.hour) unless user_signed_in?
@rss_url = rss_url @rss_url = rss_url
end end

View file

@ -7,10 +7,6 @@ class ActivityPub::BaseController < Api::BaseController
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

View file

@ -4,11 +4,12 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
include SignatureVerification include SignatureVerification
include AccountOwnedConcern include AccountOwnedConcern
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_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?

View file

@ -4,9 +4,10 @@ class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseContro
include SignatureVerification include SignatureVerification
include AccountOwnedConcern include AccountOwnedConcern
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_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

View file

@ -6,9 +6,10 @@ 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_account_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? if page_requested?
@ -16,6 +17,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
else else
expires_in(3.minutes, public: public_fetch_mode?) expires_in(3.minutes, public: public_fetch_mode?)
end 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
@ -80,8 +82,4 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
def set_account def set_account
@account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative @account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
end end
def set_cache_headers
response.headers['Vary'] = 'Signature' if authorized_fetch_mode? || page_requested?
end
end end

View file

@ -7,9 +7,10 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
DESCENDANTS_LIMIT = 60 DESCENDANTS_LIMIT = 60
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_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

View file

@ -14,6 +14,10 @@ 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?
@ -28,10 +32,6 @@ 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?

View file

@ -9,6 +9,8 @@ module Admin
before_action :set_pack before_action :set_pack
before_action :set_body_classes before_action :set_body_classes
before_action :set_cache_headers
after_action :verify_authorized after_action :verify_authorized
private private
@ -21,6 +23,10 @@ module Admin
use_pack 'admin' use_pack '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

View file

@ -2,7 +2,7 @@
module Admin module Admin
class DomainBlocksController < BaseController class DomainBlocksController < BaseController
before_action :set_domain_block, only: [:show, :destroy, :edit, :update] before_action :set_domain_block, only: [:destroy, :edit, :update]
def batch def batch
authorize :domain_block, :create? authorize :domain_block, :create?
@ -33,7 +33,7 @@ module Admin
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 # rubocop:disable Rails/OutputSafety 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
@domain_block.errors.delete(:domain) @domain_block.errors.delete(:domain)
render :new render :new
else else

View file

@ -2,8 +2,6 @@
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?
@ -59,10 +57,6 @@ module Admin
private private
def set_email_domain_block
@email_domain_block = EmailDomainBlock.find(params[:id])
end
def set_resolved_records def set_resolved_records
Resolv::DNS.open do |dns| Resolv::DNS.open do |dns|
dns.timeouts = 5 dns.timeouts = 5

View file

@ -16,6 +16,10 @@ module Admin
@role = UserRole.new @role = UserRole.new
end end
def edit
authorize @role, :update?
end
def create def create
authorize :user_role, :create? authorize :user_role, :create?
@ -30,10 +34,6 @@ module Admin
end end
end end
def edit
authorize @role, :update?
end
def update def update
authorize @role, :update? authorize @role, :update?

View file

@ -11,6 +11,10 @@ module Admin
@rule = Rule.new @rule = Rule.new
end end
def edit
authorize @rule, :update?
end
def create def create
authorize :rule, :create? authorize :rule, :create?
@ -24,10 +28,6 @@ module Admin
end end
end end
def edit
authorize @rule, :update?
end
def update def update
authorize @rule, :update? authorize @rule, :update?

View file

@ -11,6 +11,10 @@ module Admin
@warning_preset = AccountWarningPreset.new @warning_preset = AccountWarningPreset.new
end end
def edit
authorize @warning_preset, :update?
end
def create def create
authorize :account_warning_preset, :create? authorize :account_warning_preset, :create?
@ -24,10 +28,6 @@ module Admin
end end
end end
def edit
authorize @warning_preset, :update?
end
def update def update
authorize @warning_preset, :update? authorize @warning_preset, :update?

View file

@ -10,12 +10,20 @@ module Admin
@webhooks = Webhook.page(params[:page]) @webhooks = Webhook.page(params[:page])
end end
def show
authorize @webhook, :show?
end
def new def new
authorize :webhook, :create? authorize :webhook, :create?
@webhook = Webhook.new @webhook = Webhook.new
end end
def edit
authorize @webhook, :update?
end
def create def create
authorize :webhook, :create? authorize :webhook, :create?
@ -28,14 +36,6 @@ module Admin
end end
end end
def show
authorize @webhook, :show?
end
def edit
authorize @webhook, :update?
end
def update def update
authorize @webhook, :update? authorize @webhook, :update?

View file

@ -6,13 +6,14 @@ class Api::BaseController < ApplicationController
include RateLimitHeaders include RateLimitHeaders
include AccessTokenTrackingConcern include AccessTokenTrackingConcern
include ApiCachingConcern
skip_before_action :store_current_location
skip_before_action :require_functional!, unless: :whitelist_mode? skip_before_action :require_functional!, unless: :whitelist_mode?
before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access? before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access?
before_action :require_not_suspended! before_action :require_not_suspended!
before_action :set_cache_headers
vary_by 'Authorization'
protect_from_forgery with: :null_session protect_from_forgery with: :null_session
@ -148,10 +149,6 @@ class Api::BaseController < ApplicationController
doorkeeper_authorize!(*scopes) if doorkeeper_token doorkeeper_authorize!(*scopes) if doorkeeper_token
end end
def set_cache_headers
response.headers['Cache-Control'] = 'private, no-store'
end
def disallow_unauthenticated_api_access? def disallow_unauthenticated_api_access?
ENV['DISALLOW_UNAUTHENTICATED_API_ACCESS'] == 'true' || Rails.configuration.x.whitelist_mode ENV['DISALLOW_UNAUTHENTICATED_API_ACCESS'] == 'true' || Rails.configuration.x.whitelist_mode
end end

View file

@ -13,7 +13,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
def update def update
@account = current_account @account = current_account
UpdateAccountService.new.call(@account, account_params, raise_error: true) UpdateAccountService.new.call(@account, account_params, raise_error: true)
UserSettingsDecorator.new(current_user).update(user_settings_params) if user_settings_params current_user.update(user_params) if user_params
ActivityPub::UpdateDistributionWorker.perform_async(@account.id) ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
render json: @account, serializer: REST::CredentialAccountSerializer render json: @account, serializer: REST::CredentialAccountSerializer
end end
@ -34,15 +34,17 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
) )
end end
def user_settings_params def user_params
return nil if params[:source].blank? return nil if params[:source].blank?
source_params = params.require(:source) source_params = params.require(:source)
{ {
'setting_default_privacy' => source_params.fetch(:privacy, @account.user.setting_default_privacy), settings_attributes: {
'setting_default_sensitive' => source_params.fetch(:sensitive, @account.user.setting_default_sensitive), default_privacy: source_params.fetch(:privacy, @account.user.setting_default_privacy),
'setting_default_language' => source_params.fetch(:language, @account.user.setting_default_language), default_sensitive: source_params.fetch(:sensitive, @account.user.setting_default_sensitive),
default_language: source_params.fetch(:language, @account.user.setting_default_language),
},
} }
end end
end end

View file

@ -6,6 +6,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
after_action :insert_pagination_headers after_action :insert_pagination_headers
def index def index
cache_if_unauthenticated!
@accounts = load_accounts @accounts = load_accounts
render json: @accounts, each_serializer: REST::AccountSerializer render json: @accounts, each_serializer: REST::AccountSerializer
end end

View file

@ -6,6 +6,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
after_action :insert_pagination_headers after_action :insert_pagination_headers
def index def index
cache_if_unauthenticated!
@accounts = load_accounts @accounts = load_accounts
render json: @accounts, each_serializer: REST::AccountSerializer render json: @accounts, each_serializer: REST::AccountSerializer
end end

View file

@ -5,6 +5,7 @@ class Api::V1::Accounts::LookupController < Api::BaseController
before_action :set_account before_action :set_account
def show def show
cache_if_unauthenticated!
render json: @account, serializer: REST::AccountSerializer render json: @account, serializer: REST::AccountSerializer
end end

View file

@ -7,6 +7,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) } after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) }
def index def index
cache_if_unauthenticated!
@statuses = load_statuses @statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
end end

View file

@ -18,6 +18,7 @@ class Api::V1::AccountsController < Api::BaseController
override_rate_limit_headers :follow, family: :follows override_rate_limit_headers :follow, family: :follows
def show def show
cache_if_unauthenticated!
render json: @account, serializer: REST::AccountSerializer render json: @account, serializer: REST::AccountSerializer
end end

View file

@ -58,7 +58,7 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController
end end
def set_canonical_email_blocks_from_test def set_canonical_email_blocks_from_test
@canonical_email_blocks = CanonicalEmailBlock.matching_email(params[:email]) @canonical_email_blocks = CanonicalEmailBlock.matching_email(params.require(:email))
end end
def set_canonical_email_block def set_canonical_email_block

View file

@ -16,19 +16,6 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
PAGINATION_PARAMS = %i(limit).freeze PAGINATION_PARAMS = %i(limit).freeze
def create
authorize :domain_allow, :create?
@domain_allow = DomainAllow.find_by(resource_params)
if @domain_allow.nil?
@domain_allow = DomainAllow.create!(resource_params)
log_action :create, @domain_allow
end
render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
end
def index def index
authorize :domain_allow, :index? authorize :domain_allow, :index?
render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer
@ -39,6 +26,19 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
end end
def create
authorize :domain_allow, :create?
@domain_allow = DomainAllow.find_by(domain: resource_params[:domain])
if @domain_allow.nil?
@domain_allow = DomainAllow.create!(resource_params)
log_action :create, @domain_allow
end
render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
end
def destroy def destroy
authorize @domain_allow, :destroy? authorize @domain_allow, :destroy?
UnallowDomainService.new.call(@domain_allow) UnallowDomainService.new.call(@domain_allow)

View file

@ -16,6 +16,16 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
PAGINATION_PARAMS = %i(limit).freeze PAGINATION_PARAMS = %i(limit).freeze
def index
authorize :domain_block, :index?
render json: @domain_blocks, each_serializer: REST::Admin::DomainBlockSerializer
end
def show
authorize @domain_block, :show?
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end
def create def create
authorize :domain_block, :create? authorize :domain_block, :create?
@ -28,16 +38,6 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end end
def index
authorize :domain_block, :index?
render json: @domain_blocks, each_serializer: REST::Admin::DomainBlockSerializer
end
def show
authorize @domain_block, :show?
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end
def update def update
authorize @domain_block, :update? authorize @domain_block, :update?
@domain_block.update!(domain_block_params) @domain_block.update!(domain_block_params)

View file

@ -18,15 +18,6 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
limit limit
).freeze ).freeze
def create
authorize :email_domain_block, :create?
@email_domain_block = EmailDomainBlock.create!(resource_params)
log_action :create, @email_domain_block
render json: @email_domain_block, serializer: REST::Admin::EmailDomainBlockSerializer
end
def index def index
authorize :email_domain_block, :index? authorize :email_domain_block, :index?
render json: @email_domain_blocks, each_serializer: REST::Admin::EmailDomainBlockSerializer render json: @email_domain_blocks, each_serializer: REST::Admin::EmailDomainBlockSerializer
@ -37,6 +28,15 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
render json: @email_domain_block, serializer: REST::Admin::EmailDomainBlockSerializer render json: @email_domain_block, serializer: REST::Admin::EmailDomainBlockSerializer
end end
def create
authorize :email_domain_block, :create?
@email_domain_block = EmailDomainBlock.create!(resource_params)
log_action :create, @email_domain_block
render json: @email_domain_block, serializer: REST::Admin::EmailDomainBlockSerializer
end
def destroy def destroy
authorize @email_domain_block, :destroy? authorize @email_domain_block, :destroy?
@email_domain_block.destroy! @email_domain_block.destroy!

View file

@ -18,13 +18,6 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
limit limit
).freeze ).freeze
def create
authorize :ip_block, :create?
@ip_block = IpBlock.create!(resource_params)
log_action :create, @ip_block
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end
def index def index
authorize :ip_block, :index? authorize :ip_block, :index?
render json: @ip_blocks, each_serializer: REST::Admin::IpBlockSerializer render json: @ip_blocks, each_serializer: REST::Admin::IpBlockSerializer
@ -35,6 +28,13 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end end
def create
authorize :ip_block, :create?
@ip_block = IpBlock.create!(resource_params)
log_action :create, @ip_block
render json: @ip_block, serializer: REST::Admin::IpBlockSerializer
end
def update def update
authorize @ip_block, :update? authorize @ip_block, :update?
@ip_block.update(resource_params) @ip_block.update(resource_params)

View file

@ -0,0 +1,72 @@
# frozen_string_literal: true
class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseController
include Authorization
LIMIT = 100
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
before_action :set_providers, only: :index
after_action :verify_authorized
after_action :insert_pagination_headers, only: :index
PAGINATION_PARAMS = %i(limit).freeze
def index
authorize :preview_card_provider, :index?
render json: @providers, each_serializer: REST::Admin::Trends::Links::PreviewCardProviderSerializer
end
def approve
authorize :preview_card_provider, :review?
provider = PreviewCardProvider.find(params[:id])
provider.update(trendable: true, reviewed_at: Time.now.utc)
render json: provider, serializer: REST::Admin::Trends::Links::PreviewCardProviderSerializer
end
def reject
authorize :preview_card_provider, :review?
provider = PreviewCardProvider.find(params[:id])
provider.update(trendable: false, reviewed_at: Time.now.utc)
render json: provider, serializer: REST::Admin::Trends::Links::PreviewCardProviderSerializer
end
private
def set_providers
@providers = PreviewCardProvider.all.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def next_path
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
def prev_path
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(min_id: pagination_since_id)) unless @providers.empty?
end
def pagination_max_id
@providers.last.id
end
def pagination_since_id
@providers.first.id
end
def records_continue?
@providers.size == limit_param(LIMIT)
end
def pagination_params(core_params)
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
end
end

View file

@ -1,7 +1,36 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Admin::Trends::LinksController < Api::V1::Trends::LinksController class Api::V1::Admin::Trends::LinksController < Api::V1::Trends::LinksController
before_action -> { authorize_if_got_token! :'admin:read' } include Authorization
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
after_action :verify_authorized, except: :index
def index
if current_user&.can?(:manage_taxonomies)
render json: @links, each_serializer: REST::Admin::Trends::LinkSerializer
else
super
end
end
def approve
authorize :preview_card, :review?
link = PreviewCard.find(params[:id])
link.update(trendable: true)
render json: link, serializer: REST::Admin::Trends::LinkSerializer
end
def reject
authorize :preview_card, :review?
link = PreviewCard.find(params[:id])
link.update(trendable: false)
render json: link, serializer: REST::Admin::Trends::LinkSerializer
end
private private

View file

@ -1,7 +1,36 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Admin::Trends::StatusesController < Api::V1::Trends::StatusesController class Api::V1::Admin::Trends::StatusesController < Api::V1::Trends::StatusesController
before_action -> { authorize_if_got_token! :'admin:read' } include Authorization
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
after_action :verify_authorized, except: :index
def index
if current_user&.can?(:manage_taxonomies)
render json: @statuses, each_serializer: REST::Admin::Trends::StatusSerializer
else
super
end
end
def approve
authorize [:admin, :status], :review?
status = Status.find(params[:id])
status.update(trendable: true)
render json: status, serializer: REST::Admin::Trends::StatusSerializer
end
def reject
authorize [:admin, :status], :review?
status = Status.find(params[:id])
status.update(trendable: false)
render json: status, serializer: REST::Admin::Trends::StatusSerializer
end
private private

View file

@ -1,7 +1,12 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Admin::Trends::TagsController < Api::V1::Trends::TagsController class Api::V1::Admin::Trends::TagsController < Api::V1::Trends::TagsController
before_action -> { authorize_if_got_token! :'admin:read' } include Authorization
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
after_action :verify_authorized, except: :index
def index def index
if current_user&.can?(:manage_taxonomies) if current_user&.can?(:manage_taxonomies)
@ -11,6 +16,22 @@ class Api::V1::Admin::Trends::TagsController < Api::V1::Trends::TagsController
end end
end end
def approve
authorize :tag, :review?
tag = Tag.find(params[:id])
tag.update(trendable: true, reviewed_at: Time.now.utc)
render json: tag, serializer: REST::Admin::TagSerializer
end
def reject
authorize :tag, :review?
tag = Tag.find(params[:id])
tag.update(trendable: false, reviewed_at: Time.now.utc)
render json: tag, serializer: REST::Admin::TagSerializer
end
private private
def enabled? def enabled?

View file

@ -1,10 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::CustomEmojisController < Api::BaseController class Api::V1::CustomEmojisController < Api::BaseController
skip_before_action :set_cache_headers vary_by '', unless: :disallow_unauthenticated_api_access?
def index def index
expires_in 3.minutes, public: true cache_even_if_authenticated! unless disallow_unauthenticated_api_access?
render_with_cache(each_serializer: REST::CustomEmojiSerializer) { CustomEmoji.listed.includes(:category) } render_with_cache(each_serializer: REST::CustomEmojiSerializer) { CustomEmoji.listed.includes(:category) }
end end
end end

View file

@ -5,6 +5,7 @@ class Api::V1::DirectoriesController < Api::BaseController
before_action :set_accounts before_action :set_accounts
def show def show
cache_if_unauthenticated!
render json: @accounts, each_serializer: REST::AccountSerializer render json: @accounts, each_serializer: REST::AccountSerializer
end end

View file

@ -1,9 +1,10 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Emails::ConfirmationsController < Api::BaseController class Api::V1::Emails::ConfirmationsController < Api::BaseController
before_action -> { doorkeeper_authorize! :write, :'write:accounts' } before_action -> { authorize_if_got_token! :read, :'read:accounts' }, only: :check
before_action :require_user_owned_by_application! before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :check
before_action :require_user_not_confirmed! before_action :require_user_owned_by_application!, except: :check
before_action :require_user_not_confirmed!, except: :check
def create def create
current_user.update!(email: params[:email]) if params.key?(:email) current_user.update!(email: params[:email]) if params.key?(:email)
@ -12,6 +13,10 @@ class Api::V1::Emails::ConfirmationsController < Api::BaseController
render_empty render_empty
end end
def check
render json: current_user.confirmed?
end
private private
def require_user_owned_by_application! def require_user_owned_by_application!

View file

@ -13,7 +13,7 @@ class Api::V1::FeaturedTagsController < Api::BaseController
end end
def create def create
featured_tag = CreateFeaturedTagService.new.call(current_account, featured_tag_params[:name]) featured_tag = CreateFeaturedTagService.new.call(current_account, params.require(:name))
render json: featured_tag, serializer: REST::FeaturedTagSerializer render json: featured_tag, serializer: REST::FeaturedTagSerializer
end end
@ -33,6 +33,6 @@ class Api::V1::FeaturedTagsController < Api::BaseController
end end
def featured_tag_params def featured_tag_params
params.permit(:name) params.require(:name)
end end
end end

View file

@ -11,6 +11,10 @@ class Api::V1::FiltersController < Api::BaseController
render json: @filters, each_serializer: REST::V1::FilterSerializer render json: @filters, each_serializer: REST::V1::FilterSerializer
end end
def show
render json: @filter, serializer: REST::V1::FilterSerializer
end
def create def create
ApplicationRecord.transaction do ApplicationRecord.transaction do
filter_category = current_account.custom_filters.create!(filter_params) filter_category = current_account.custom_filters.create!(filter_params)
@ -20,10 +24,6 @@ class Api::V1::FiltersController < Api::BaseController
render json: @filter, serializer: REST::V1::FilterSerializer render json: @filter, serializer: REST::V1::FilterSerializer
end end
def show
render json: @filter, serializer: REST::V1::FilterSerializer
end
def update def update
ApplicationRecord.transaction do ApplicationRecord.transaction do
@filter.update!(keyword_params) @filter.update!(keyword_params)

View file

@ -3,11 +3,12 @@
class Api::V1::Instances::ActivityController < Api::BaseController class Api::V1::Instances::ActivityController < Api::BaseController
before_action :require_enabled_api! before_action :require_enabled_api!
skip_before_action :set_cache_headers
skip_before_action :require_authenticated_user!, unless: :whitelist_mode? skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
vary_by ''
def show def show
expires_in 1.day, public: true cache_even_if_authenticated!
render_with_cache json: :activity, expires_in: 1.day render_with_cache json: :activity, expires_in: 1.day
end end

View file

@ -6,8 +6,15 @@ class Api::V1::Instances::DomainBlocksController < Api::BaseController
before_action :require_enabled_api! before_action :require_enabled_api!
before_action :set_domain_blocks before_action :set_domain_blocks
vary_by '', if: -> { Setting.show_domain_blocks == 'all' }
def index def index
expires_in 3.minutes, public: true if Setting.show_domain_blocks == 'all'
cache_even_if_authenticated!
else
cache_if_unauthenticated!
end
render json: @domain_blocks, each_serializer: REST::DomainBlockSerializer, with_comment: (Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?)) render json: @domain_blocks, each_serializer: REST::DomainBlockSerializer, with_comment: (Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?))
end end

View file

@ -2,11 +2,19 @@
class Api::V1::Instances::ExtendedDescriptionsController < Api::BaseController class Api::V1::Instances::ExtendedDescriptionsController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :whitelist_mode? skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
skip_around_action :set_locale
before_action :set_extended_description before_action :set_extended_description
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if whitelist_mode?
end
def show def show
expires_in 3.minutes, public: true cache_even_if_authenticated!
render json: @extended_description, serializer: REST::ExtendedDescriptionSerializer render json: @extended_description, serializer: REST::ExtendedDescriptionSerializer
end end

View file

@ -3,11 +3,18 @@
class Api::V1::Instances::PeersController < Api::BaseController class Api::V1::Instances::PeersController < Api::BaseController
before_action :require_enabled_api! before_action :require_enabled_api!
skip_before_action :set_cache_headers
skip_before_action :require_authenticated_user!, unless: :whitelist_mode? skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
skip_around_action :set_locale
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if whitelist_mode?
end
def index def index
expires_in 1.day, public: true cache_even_if_authenticated!
render_with_cache(expires_in: 1.day) { Instance.where.not(domain: DomainBlock.select(:domain)).pluck(:domain) } render_with_cache(expires_in: 1.day) { Instance.where.not(domain: DomainBlock.select(:domain)).pluck(:domain) }
end end

View file

@ -5,8 +5,10 @@ class Api::V1::Instances::PrivacyPoliciesController < Api::BaseController
before_action :set_privacy_policy before_action :set_privacy_policy
vary_by ''
def show def show
expires_in 1.day, public: true cache_even_if_authenticated!
render json: @privacy_policy, serializer: REST::PrivacyPolicySerializer render json: @privacy_policy, serializer: REST::PrivacyPolicySerializer
end end

View file

@ -2,10 +2,19 @@
class Api::V1::Instances::RulesController < Api::BaseController class Api::V1::Instances::RulesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :whitelist_mode? skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
skip_around_action :set_locale
before_action :set_rules before_action :set_rules
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if whitelist_mode?
end
def index def index
cache_even_if_authenticated!
render json: @rules, each_serializer: REST::RuleSerializer render json: @rules, each_serializer: REST::RuleSerializer
end end

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
class Api::V1::Instances::TranslationLanguagesController < Api::BaseController
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
before_action :set_languages
vary_by ''
def show
cache_even_if_authenticated!
render json: @languages
end
private
def set_languages
if TranslationService.configured?
@languages = Rails.cache.fetch('translation_service/languages', expires_in: 7.days, race_condition_ttl: 1.hour) { TranslationService.configured.languages }
@languages['und'] = @languages.delete(nil) if @languages.key?(nil)
else
@languages = {}
end
end
end

View file

@ -1,11 +1,18 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::InstancesController < Api::BaseController class Api::V1::InstancesController < Api::BaseController
skip_before_action :set_cache_headers
skip_before_action :require_authenticated_user!, unless: :whitelist_mode? skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
skip_around_action :set_locale
vary_by ''
# Override `current_user` to avoid reading session cookies unless in whitelist mode
def current_user
super if whitelist_mode?
end
def show def show
expires_in 3.minutes, public: true cache_even_if_authenticated!
render_with_cache json: InstancePresenter.new, serializer: REST::V1::InstanceSerializer, root: 'instance' render_with_cache json: InstancePresenter.new, serializer: REST::V1::InstanceSerializer, root: 'instance'
end end
end end

View file

@ -6,19 +6,20 @@ class Api::V1::MediaController < Api::BaseController
before_action :set_media_attachment, except: [:create] before_action :set_media_attachment, except: [:create]
before_action :check_processing, except: [:create] before_action :check_processing, except: [:create]
def show
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
end
def create def create
@media_attachment = current_account.media_attachments.create!(media_attachment_params) @media_attachment = current_account.media_attachments.create!(media_attachment_params)
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer render json: @media_attachment, serializer: REST::MediaAttachmentSerializer
rescue Paperclip::Errors::NotIdentifiedByImageMagickError rescue Paperclip::Errors::NotIdentifiedByImageMagickError
render json: file_type_error, status: 422 render json: file_type_error, status: 422
rescue Paperclip::Error rescue Paperclip::Error => e
Rails.logger.error "#{e.class}: #{e.message}"
render json: processing_error, status: 500 render json: processing_error, status: 500
end end
def show
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
end
def update def update
@media_attachment.update!(updateable_media_attachment_params) @media_attachment.update!(updateable_media_attachment_params)
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment

View file

@ -8,6 +8,7 @@ class Api::V1::PollsController < Api::BaseController
before_action :refresh_poll before_action :refresh_poll
def show def show
cache_if_unauthenticated!
render json: @poll, serializer: REST::PollSerializer, include_results: true render json: @poll, serializer: REST::PollSerializer, include_results: true
end end

View file

@ -6,6 +6,10 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
before_action :set_push_subscription before_action :set_push_subscription
before_action :check_push_subscription, only: [:show, :update] before_action :check_push_subscription, only: [:show, :update]
def show
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
end
def create def create
@push_subscription&.destroy! @push_subscription&.destroy!
@ -21,10 +25,6 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
end end
def show
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
end
def update def update
@push_subscription.update!(data: data_params) @push_subscription.update!(data: data_params)
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer

View file

@ -8,6 +8,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
after_action :insert_pagination_headers after_action :insert_pagination_headers
def index def index
cache_if_unauthenticated!
@accounts = load_accounts @accounts = load_accounts
render json: @accounts, each_serializer: REST::AccountSerializer render json: @accounts, each_serializer: REST::AccountSerializer
end end

View file

@ -7,6 +7,7 @@ class Api::V1::Statuses::HistoriesController < Api::BaseController
before_action :set_status before_action :set_status
def show def show
cache_if_unauthenticated!
render json: @status.edits.includes(:account, status: [:account]), each_serializer: REST::StatusEditSerializer render json: @status.edits.includes(:account, status: [:account]), each_serializer: REST::StatusEditSerializer
end end

View file

@ -9,17 +9,23 @@ class Api::V1::Statuses::ReactionsController < Api::BaseController
def create def create
ReactService.new.call(current_account, @status, params[:id]) ReactService.new.call(current_account, @status, params[:id])
render_empty render json: @status, serializer: REST::StatusSerializer
end end
def destroy def destroy
UnreactService.new.call(current_account, @status, params[:id]) UnreactWorker.perform_async(current_account.id, @status.id, params[:id])
render_empty
render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, reactions_map: { @status.id => false })
rescue Mastodon::NotPermittedError
not_found
end end
private private
def set_status def set_status
@status = Status.find(params[:status_id]) @status = Status.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
not_found
end end
end end

View file

@ -8,6 +8,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
after_action :insert_pagination_headers after_action :insert_pagination_headers
def index def index
cache_if_unauthenticated!
@accounts = load_accounts @accounts = load_accounts
render json: @accounts, each_serializer: REST::AccountSerializer render json: @accounts, each_serializer: REST::AccountSerializer
end end

View file

@ -2,6 +2,8 @@
class Api::V1::Statuses::ReblogsController < Api::BaseController class Api::V1::Statuses::ReblogsController < Api::BaseController
include Authorization include Authorization
include Redisable
include Lockable
before_action -> { doorkeeper_authorize! :write, :'write:statuses' } before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
before_action :require_user! before_action :require_user!
@ -10,7 +12,9 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
override_rate_limit_headers :create, family: :statuses override_rate_limit_headers :create, family: :statuses
def create def create
with_redis_lock("reblog:#{current_account.id}:#{@reblog.id}") do
@status = ReblogService.new.call(current_account, @reblog, reblog_params) @status = ReblogService.new.call(current_account, @reblog, reblog_params)
end
render json: @status, serializer: REST::StatusSerializer render json: @status, serializer: REST::StatusSerializer
end end

View file

@ -24,11 +24,14 @@ class Api::V1::StatusesController < Api::BaseController
DESCENDANTS_DEPTH_LIMIT = 20 DESCENDANTS_DEPTH_LIMIT = 20
def show def show
cache_if_unauthenticated!
@status = cache_collection([@status], Status).first @status = cache_collection([@status], Status).first
render json: @status, serializer: REST::StatusSerializer render json: @status, serializer: REST::StatusSerializer
end end
def context def context
cache_if_unauthenticated!
ancestors_limit = CONTEXT_LIMIT ancestors_limit = CONTEXT_LIMIT
descendants_limit = CONTEXT_LIMIT descendants_limit = CONTEXT_LIMIT
descendants_depth_limit = nil descendants_depth_limit = nil

View file

@ -5,7 +5,7 @@ class Api::V1::StreamingController < Api::BaseController
if Rails.configuration.x.streaming_api_base_url == request.host if Rails.configuration.x.streaming_api_base_url == request.host
not_found not_found
else else
redirect_to streaming_api_url, status: 301 redirect_to streaming_api_url, status: 301, allow_other_host: true
end end
end end

View file

@ -8,6 +8,7 @@ class Api::V1::TagsController < Api::BaseController
override_rate_limit_headers :follow, family: :follows override_rate_limit_headers :follow, family: :follows
def show def show
cache_if_unauthenticated!
render json: @tag, serializer: REST::TagSerializer render json: @tag, serializer: REST::TagSerializer
end end

View file

@ -5,6 +5,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
after_action :insert_pagination_headers, unless: -> { @statuses.empty? } after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
def show def show
cache_if_unauthenticated!
@statuses = load_statuses @statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
end end
@ -40,7 +41,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
only_media: truthy_param?(:only_media), only_media: truthy_param?(:only_media),
allow_local_only: truthy_param?(:allow_local_only), allow_local_only: truthy_param?(:allow_local_only),
with_replies: Setting.show_replies_in_public_timelines, with_replies: Setting.show_replies_in_public_timelines,
with_reblogs: Setting.show_reblogs_in_public_timelines, with_reblogs: Setting.show_reblogs_in_public_timelines
) )
end end

View file

@ -5,6 +5,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
after_action :insert_pagination_headers, unless: -> { @statuses.empty? } after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
def show def show
cache_if_unauthenticated!
@statuses = load_statuses @statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
end end

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Trends::LinksController < Api::BaseController class Api::V1::Trends::LinksController < Api::BaseController
vary_by 'Authorization, Accept-Language'
before_action :set_links before_action :set_links
after_action :insert_pagination_headers after_action :insert_pagination_headers
@ -8,6 +10,7 @@ class Api::V1::Trends::LinksController < Api::BaseController
DEFAULT_LINKS_LIMIT = 10 DEFAULT_LINKS_LIMIT = 10
def index def index
cache_if_unauthenticated!
render json: @links, each_serializer: REST::Trends::LinkSerializer render json: @links, each_serializer: REST::Trends::LinkSerializer
end end

View file

@ -1,11 +1,14 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::Trends::StatusesController < Api::BaseController class Api::V1::Trends::StatusesController < Api::BaseController
vary_by 'Authorization, Accept-Language'
before_action :set_statuses before_action :set_statuses
after_action :insert_pagination_headers after_action :insert_pagination_headers
def index def index
cache_if_unauthenticated!
render json: @statuses, each_serializer: REST::StatusSerializer render json: @statuses, each_serializer: REST::StatusSerializer
end end

View file

@ -8,6 +8,7 @@ class Api::V1::Trends::TagsController < Api::BaseController
DEFAULT_TAGS_LIMIT = (ENV['MAX_TRENDING_TAGS'] || 10).to_i DEFAULT_TAGS_LIMIT = (ENV['MAX_TRENDING_TAGS'] || 10).to_i
def index def index
cache_if_unauthenticated!
render json: @tags, each_serializer: REST::TagSerializer, relationships: TagRelationshipsPresenter.new(@tags, current_user&.account_id) render json: @tags, each_serializer: REST::TagSerializer, relationships: TagRelationshipsPresenter.new(@tags, current_user&.account_id)
end end

View file

@ -12,13 +12,13 @@ class Api::V2::Filters::KeywordsController < Api::BaseController
render json: @keywords, each_serializer: REST::FilterKeywordSerializer render json: @keywords, each_serializer: REST::FilterKeywordSerializer
end end
def create def show
@keyword = current_account.custom_filters.find(params[:filter_id]).keywords.create!(resource_params)
render json: @keyword, serializer: REST::FilterKeywordSerializer render json: @keyword, serializer: REST::FilterKeywordSerializer
end end
def show def create
@keyword = current_account.custom_filters.find(params[:filter_id]).keywords.create!(resource_params)
render json: @keyword, serializer: REST::FilterKeywordSerializer render json: @keyword, serializer: REST::FilterKeywordSerializer
end end

View file

@ -12,13 +12,13 @@ class Api::V2::Filters::StatusesController < Api::BaseController
render json: @status_filters, each_serializer: REST::FilterStatusSerializer render json: @status_filters, each_serializer: REST::FilterStatusSerializer
end end
def create def show
@status_filter = current_account.custom_filters.find(params[:filter_id]).statuses.create!(resource_params)
render json: @status_filter, serializer: REST::FilterStatusSerializer render json: @status_filter, serializer: REST::FilterStatusSerializer
end end
def show def create
@status_filter = current_account.custom_filters.find(params[:filter_id]).statuses.create!(resource_params)
render json: @status_filter, serializer: REST::FilterStatusSerializer render json: @status_filter, serializer: REST::FilterStatusSerializer
end end

View file

@ -11,13 +11,13 @@ class Api::V2::FiltersController < Api::BaseController
render json: @filters, each_serializer: REST::FilterSerializer, rules_requested: true render json: @filters, each_serializer: REST::FilterSerializer, rules_requested: true
end end
def create def show
@filter = current_account.custom_filters.create!(resource_params)
render json: @filter, serializer: REST::FilterSerializer, rules_requested: true render json: @filter, serializer: REST::FilterSerializer, rules_requested: true
end end
def show def create
@filter = current_account.custom_filters.create!(resource_params)
render json: @filter, serializer: REST::FilterSerializer, rules_requested: true render json: @filter, serializer: REST::FilterSerializer, rules_requested: true
end end

View file

@ -2,7 +2,7 @@
class Api::V2::InstancesController < Api::V1::InstancesController class Api::V2::InstancesController < Api::V1::InstancesController
def show def show
expires_in 3.minutes, public: true cache_even_if_authenticated!
render_with_cache json: InstancePresenter.new, serializer: REST::InstanceSerializer, root: 'instance' render_with_cache json: InstancePresenter.new, serializer: REST::InstanceSerializer, root: 'instance'
end end
end end

Some files were not shown because too many files have changed in this diff Show more