Compare commits
254 Commits
acf635ffe8
...
849d7bff51
Author | SHA1 | Date |
---|---|---|
|
849d7bff51 | |
|
00412e8037 | |
![]() |
f08f6d20e6 | |
![]() |
ea04f33f50 | |
![]() |
3d9e35375c | |
![]() |
a33d6c946a | |
![]() |
e8243d5bbd | |
![]() |
5f0d2b6e3b | |
![]() |
f3af434c25 | |
![]() |
f4e3e309b1 | |
![]() |
bbd0e9caa6 | |
![]() |
a8939e9098 | |
![]() |
10f5329ddf | |
![]() |
9ab89bb832 | |
![]() |
20f1f3aa7d | |
![]() |
8b31030fe4 | |
![]() |
d77fbbed73 | |
![]() |
f89f3a8566 | |
![]() |
61f3e0e95e | |
![]() |
8bf9bd5ac8 | |
![]() |
75e28731a5 | |
![]() |
aff2d55b80 | |
![]() |
a49707dacb | |
![]() |
7835f8fd22 | |
![]() |
e9eab013e7 | |
![]() |
51479f5c28 | |
![]() |
09054f5485 | |
![]() |
2d029dedd9 | |
![]() |
5d18840ab9 | |
![]() |
16c5354b8c | |
![]() |
de74acbe0c | |
![]() |
ed0a407888 | |
![]() |
179e38cf15 | |
![]() |
3fb7fe14c6 | |
![]() |
9b59748679 | |
![]() |
6f64c79ca4 | |
![]() |
a6207d243b | |
![]() |
f877aa9d70 | |
![]() |
746979f75d | |
![]() |
f258478395 | |
![]() |
c9e040fb24 | |
![]() |
5811ccc611 | |
![]() |
c0ea33e3fc | |
![]() |
e675c10d19 | |
![]() |
ac41a9712e | |
![]() |
c9210af3ee | |
![]() |
64fae0efb5 | |
![]() |
0b249ebdb0 | |
![]() |
830e6cefae | |
![]() |
569b39256b | |
![]() |
880e661d53 | |
![]() |
ff974395c2 | |
![]() |
849d93e50a | |
![]() |
c3c7d59072 | |
![]() |
f95125bd04 | |
![]() |
27bafabb64 | |
![]() |
e1ebcc007d | |
![]() |
ff3b7069cf | |
![]() |
da3bd913ae | |
![]() |
d5a185d721 | |
![]() |
1fe04f740a | |
![]() |
c97b611b6b | |
![]() |
710745e16b | |
![]() |
cf18cc2891 | |
![]() |
bdcd8a9e88 | |
![]() |
08fb9d300a | |
![]() |
2c6c398c60 | |
![]() |
a1cca1c8b6 | |
![]() |
d9a958fcf7 | |
![]() |
b25860c509 | |
![]() |
a2a22bad23 | |
![]() |
1e75eb690d | |
![]() |
45579a26cf | |
![]() |
0999cb4601 | |
![]() |
c98b012583 | |
![]() |
9a52a7f7a0 | |
![]() |
e38b391940 | |
![]() |
9b8cb947a7 | |
![]() |
3df665fd23 | |
![]() |
8b636a29c6 | |
![]() |
a0c9f2447e | |
![]() |
97385f27bd | |
![]() |
9c1929efad | |
![]() |
d37c0a1060 | |
![]() |
668a19a2f3 | |
![]() |
05e3abe9d9 | |
![]() |
8d61d2b0da | |
![]() |
8f7c172eb8 | |
![]() |
b0ebaeb691 | |
![]() |
1d49718a84 | |
![]() |
14a7e414fc | |
![]() |
8227af8dcc | |
![]() |
2839fbc733 | |
![]() |
4acf5f8971 | |
![]() |
4b87e2a8db | |
![]() |
b75c353962 | |
![]() |
18f58f4284 | |
![]() |
24491abf6d | |
![]() |
b5c4b47746 | |
![]() |
38b2974a83 | |
![]() |
f1c1dd0118 | |
![]() |
a7df578f97 | |
![]() |
c26b1b0a1c | |
![]() |
389f0443c8 | |
![]() |
570079f8ce | |
![]() |
bae694108a | |
![]() |
9189e90ff2 | |
![]() |
5e060e1f44 | |
![]() |
41eb49b984 | |
![]() |
a89b02af92 | |
![]() |
1ed0ff30d3 | |
![]() |
b233da5996 | |
![]() |
8131a5b330 | |
![]() |
6693a4fe7c | |
![]() |
598e63dad2 | |
![]() |
1eb51bd749 | |
![]() |
88d33f361f | |
![]() |
f50105779b | |
![]() |
5a5975d7f7 | |
![]() |
32a030dd74 | |
![]() |
0ad2413b35 | |
![]() |
f1c1fa1411 | |
![]() |
fc56eda94b | |
![]() |
15fd712464 | |
![]() |
81f75b1e0e | |
![]() |
c53fe9b753 | |
![]() |
d902a707a3 | |
![]() |
d00e45a7d3 | |
![]() |
af824db398 | |
![]() |
c18884de32 | |
![]() |
6b95aaaa65 | |
![]() |
89c01383f9 | |
![]() |
0a08e9d3d3 | |
![]() |
c23d285b16 | |
![]() |
8f6e290c7a | |
![]() |
0669822ae8 | |
![]() |
242d7864f1 | |
![]() |
56cf092058 | |
![]() |
fa14976a5d | |
![]() |
819daeb651 | |
![]() |
921bef6799 | |
![]() |
e8fe941015 | |
![]() |
2e43461100 | |
![]() |
5a2aa06a51 | |
![]() |
bdc74086e6 | |
![]() |
6e226f5a32 | |
![]() |
470b8abb69 | |
![]() |
60ac9e8634 | |
![]() |
8dcfb6e0ea | |
![]() |
678d836c7d | |
![]() |
cf1bc4bb93 | |
![]() |
f22b4e556c | |
![]() |
bfeccf6748 | |
![]() |
274d561430 | |
![]() |
e0d075713f | |
![]() |
4cfe52635c | |
![]() |
e79998a11a | |
![]() |
38eeed6cbf | |
![]() |
1033598416 | |
![]() |
edec08b970 | |
![]() |
cb97a92954 | |
![]() |
103b6de8b2 | |
![]() |
7b01b7c3bf | |
![]() |
8015297f9e | |
![]() |
374a109546 | |
![]() |
0091b28ffe | |
![]() |
11b34a903a | |
![]() |
0a813d96db | |
![]() |
66bda4713e | |
![]() |
612a1ee697 | |
![]() |
12b935fadf | |
![]() |
105f8687e4 | |
![]() |
2a3a110f00 | |
![]() |
faa336e3f7 | |
![]() |
8979b70975 | |
![]() |
1c61869eed | |
![]() |
6028d047b9 | |
![]() |
2b0f1f365a | |
![]() |
7cf963eec2 | |
![]() |
a5bc4ea550 | |
![]() |
ece38b9318 | |
![]() |
8e514b1965 | |
![]() |
d9e9579832 | |
![]() |
1d9969fadf | |
![]() |
49fad26eca | |
![]() |
d8a06c1375 | |
![]() |
d4511f2a76 | |
![]() |
1565af1caf | |
![]() |
5841f1af8c | |
![]() |
a3393d0d07 | |
![]() |
91a8cd21d8 | |
![]() |
3029aeb838 | |
![]() |
185a71f281 | |
![]() |
b839babb39 | |
![]() |
785b0349eb | |
![]() |
872c4e1ef2 | |
![]() |
90beba57d8 | |
![]() |
c7cd891e86 | |
![]() |
6403d7841e | |
![]() |
93a84f4704 | |
![]() |
2f5608e9e5 | |
![]() |
5f624954be | |
![]() |
9650a5738a | |
![]() |
dcdc614bd2 | |
![]() |
b31ee9ab38 | |
![]() |
1820b55a11 | |
![]() |
0c66358601 | |
![]() |
855cf7802d | |
![]() |
fba60094a2 | |
![]() |
b0bf6216e6 | |
![]() |
62ab7506d6 | |
![]() |
301e03eb8c | |
![]() |
36631e40cc | |
![]() |
1527b02c6d | |
![]() |
1419f90ef2 | |
![]() |
678480d4d3 | |
![]() |
aea7866161 | |
![]() |
276c39361b | |
![]() |
6084461cd0 | |
![]() |
c35e3cb6ac | |
![]() |
8099ba04be | |
![]() |
e9a79d46cd | |
![]() |
1ac9219b31 | |
![]() |
930d84d40e | |
![]() |
f45961aa98 | |
![]() |
804aa8d501 | |
![]() |
2daa5a1549 | |
![]() |
290e4aba31 | |
![]() |
0c81eec239 | |
![]() |
03ea084f0d | |
![]() |
0bfd9f7f73 | |
![]() |
5141697323 | |
![]() |
2904fd0fdd | |
![]() |
0c7ce98ff6 | |
![]() |
ef3675d688 | |
![]() |
0a5f0a8b20 | |
![]() |
e1b4eeb636 | |
![]() |
e713c545b8 | |
![]() |
4687967176 | |
![]() |
528b8e7e3a | |
![]() |
58a1b2e330 | |
![]() |
5dc3173ef8 | |
![]() |
0461f83320 | |
![]() |
9d75b03ba4 | |
![]() |
501d6197c4 | |
![]() |
fbb4de3dbc | |
![]() |
b0eba1a060 | |
![]() |
88ce59505e | |
![]() |
37886c28da | |
![]() |
faf657d709 | |
![]() |
c62604b5f6 | |
![]() |
e798b8615c | |
![]() |
c1a7e38d2b | |
![]() |
e98c86050a |
|
@ -26,7 +26,6 @@ services:
|
|||
ports:
|
||||
- '127.0.0.1:3000:3000'
|
||||
- '127.0.0.1:4000:4000'
|
||||
- '127.0.0.1:80:3000'
|
||||
networks:
|
||||
- external_network
|
||||
- internal_network
|
||||
|
|
34
.eslintrc.js
34
.eslintrc.js
|
@ -7,6 +7,7 @@ module.exports = {
|
|||
'plugin:jsx-a11y/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:jsdoc/recommended',
|
||||
],
|
||||
|
||||
env: {
|
||||
|
@ -27,6 +28,7 @@ module.exports = {
|
|||
'import',
|
||||
'promise',
|
||||
'@typescript-eslint',
|
||||
'formatjs',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
|
@ -71,7 +73,7 @@ module.exports = {
|
|||
'comma-style': ['warn', 'last'],
|
||||
'consistent-return': 'error',
|
||||
'dot-notation': 'error',
|
||||
eqeqeq: 'error',
|
||||
eqeqeq: ['error', 'always', { 'null': 'ignore' }],
|
||||
indent: ['warn', 2],
|
||||
'jsx-quotes': ['error', 'prefer-single'],
|
||||
'no-case-declarations': 'off',
|
||||
|
@ -218,6 +220,33 @@ module.exports = {
|
|||
'promise/no-callback-in-promise': 'off',
|
||||
'promise/no-nesting': 'off',
|
||||
'promise/no-promise-in-callback': 'off',
|
||||
|
||||
'formatjs/blocklist-elements': 'error',
|
||||
'formatjs/enforce-default-message': ['error', 'literal'],
|
||||
'formatjs/enforce-description': 'off', // description values not currently used
|
||||
'formatjs/enforce-id': 'off', // Explicit IDs are used in the project
|
||||
'formatjs/enforce-placeholders': 'off', // Issues in short_number.jsx
|
||||
'formatjs/enforce-plural-rules': 'error',
|
||||
'formatjs/no-camel-case': 'off', // disabledAccount is only non-conforming
|
||||
'formatjs/no-complex-selectors': 'error',
|
||||
'formatjs/no-emoji': 'error',
|
||||
'formatjs/no-id': 'off', // IDs are used for translation keys
|
||||
'formatjs/no-invalid-icu': 'error',
|
||||
'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings
|
||||
'formatjs/no-multiple-plurals': 'off', // Only used by hashtag.jsx
|
||||
'formatjs/no-multiple-whitespaces': 'error',
|
||||
'formatjs/no-offset': 'error',
|
||||
'formatjs/no-useless-message': 'error',
|
||||
'formatjs/prefer-formatted-message': 'error',
|
||||
'formatjs/prefer-pound-in-plural': 'error',
|
||||
|
||||
'jsdoc/check-types': 'off',
|
||||
'jsdoc/no-undefined-types': 'off',
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
'jsdoc/require-param-description': 'off',
|
||||
'jsdoc/require-property-description': 'off',
|
||||
'jsdoc/require-returns-description': 'off',
|
||||
'jsdoc/require-returns': 'off',
|
||||
},
|
||||
|
||||
overrides: [
|
||||
|
@ -250,10 +279,13 @@ module.exports = {
|
|||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:jsdoc/recommended',
|
||||
],
|
||||
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -43,9 +43,16 @@ jobs:
|
|||
type=edge,branch=main
|
||||
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
|
||||
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 }}
|
||||
|
|
|
@ -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
|
|
@ -48,7 +48,7 @@ jobs:
|
|||
run: yarn --frozen-lockfile
|
||||
|
||||
- name: ESLint
|
||||
run: yarn test:lint:js
|
||||
run: yarn test:lint:js --max-warnings 0
|
||||
|
||||
- name: Typecheck
|
||||
run: yarn test:typecheck
|
||||
|
|
|
@ -9,7 +9,6 @@ on:
|
|||
env:
|
||||
BUNDLE_CLEAN: true
|
||||
BUNDLE_FROZEN: true
|
||||
BUNDLE_WITHOUT: 'development production'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
|
@ -19,8 +18,17 @@ jobs:
|
|||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
mode:
|
||||
- production
|
||||
- test
|
||||
env:
|
||||
RAILS_ENV: test
|
||||
RAILS_ENV: ${{ matrix.mode }}
|
||||
BUNDLE_WITH: ${{ matrix.mode }}
|
||||
OTP_SECRET: precompile_placeholder
|
||||
SECRET_KEY_BASE: precompile_placeholder
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
@ -50,6 +58,7 @@ jobs:
|
|||
./bin/rails assets:precompile
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: matrix.mode == 'test'
|
||||
with:
|
||||
path: |-
|
||||
./public/assets
|
||||
|
@ -97,14 +106,13 @@ jobs:
|
|||
PAM_ENABLED: true
|
||||
PAM_DEFAULT_SERVICE: pam_test
|
||||
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
||||
BUNDLE_WITH: 'pam_authentication'
|
||||
BUNDLE_WITH: 'pam_authentication test'
|
||||
CI_JOBS: ${{ matrix.ci_job }}/4
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ruby-version:
|
||||
- '2.7'
|
||||
- '3.0'
|
||||
- '3.1'
|
||||
- '.ruby-version'
|
||||
|
@ -136,10 +144,6 @@ jobs:
|
|||
ruby-version: ${{ matrix.ruby-version}}
|
||||
bundler-cache: true
|
||||
|
||||
- name: Update system gems
|
||||
if: matrix.ruby-version == '2.7'
|
||||
run: gem update --system
|
||||
|
||||
- name: Load database schema
|
||||
run: './bin/rails db:create db:schema:load db:seed'
|
||||
|
||||
|
|
2
.profile
2
.profile
|
@ -1 +1 @@
|
|||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/.apt/lib/x86_64-linux-gnu:/app/.apt/usr/lib/x86_64-linux-gnu/mesa:/app/.apt/usr/lib/x86_64-linux-gnu/pulseaudio
|
||||
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
|
||||
|
|
10
.rubocop.yml
10
.rubocop.yml
|
@ -13,7 +13,7 @@ require:
|
|||
- rubocop-capybara
|
||||
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.7 # Set to minimum supported version of CI
|
||||
TargetRubyVersion: 3.0 # Set to minimum supported version of CI
|
||||
DisplayCopNames: true
|
||||
DisplayStyleGuide: true
|
||||
ExtraDetails: true
|
||||
|
@ -65,6 +65,7 @@ Metrics/AbcSize:
|
|||
Metrics/BlockLength:
|
||||
CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
|
||||
Exclude:
|
||||
- 'config/routes.rb'
|
||||
- 'lib/mastodon/*_cli.rb'
|
||||
- 'lib/tasks/*.rake'
|
||||
- 'app/models/concerns/account_associations.rb'
|
||||
|
@ -85,6 +86,7 @@ Metrics/BlockLength:
|
|||
- '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'
|
||||
|
@ -130,6 +132,7 @@ Metrics/ClassLength:
|
|||
- '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'
|
||||
|
@ -158,6 +161,11 @@ Metrics/MethodLength:
|
|||
Metrics/ModuleLength:
|
||||
CountAsOne: [array, heredoc]
|
||||
|
||||
# Reason: Prevailing style is argument file paths
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath
|
||||
Rails/FilePath:
|
||||
EnforcedStyle: arguments
|
||||
|
||||
# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus
|
||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
|
||||
Rails/HttpStatus:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
12
Dockerfile
12
Dockerfile
|
@ -42,7 +42,7 @@ RUN \
|
|||
bundle config set --local without 'development test' && \
|
||||
bundle config set silence_root_warning true && \
|
||||
bundle install -j"$(nproc)" && \
|
||||
yarn install --immutable && \
|
||||
yarn install && \
|
||||
yarn cache clean
|
||||
|
||||
# Precompile assets
|
||||
|
@ -58,12 +58,16 @@ ENV RAILS_ENV="production" \
|
|||
ENV OTP_SECRET=precompile_placeholder \
|
||||
SECRET_KEY_BASE=precompile_placeholder \
|
||||
RAKE_NO_YARN_INSTALL_HACK=1
|
||||
RUN mv ./emoji_data/all.json ./node_modules/emoji-mart/data/all.json && \
|
||||
RUN mv ./emoji_data/all.json ./node_modules/emoji-mart/data/all.json && yarn install && \
|
||||
bundle exec rails assets:precompile
|
||||
|
||||
|
||||
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 GID="991"
|
||||
|
||||
|
@ -108,7 +112,9 @@ ENV RAILS_ENV="production" \
|
|||
NODE_ENV="production" \
|
||||
RAILS_SERVE_STATIC_FILES="true" \
|
||||
BIND="0.0.0.0" \
|
||||
SOURCE_TAG="${SOURCE_TAG}"
|
||||
SOURCE_TAG="${SOURCE_TAG}" \
|
||||
MASTODON_VERSION_FLAGS="${MASTODON_VERSION_FLAGS}" \
|
||||
MASTODON_VERSION_SUFFIX="${MASTODON_VERSION_SUFFIX}"
|
||||
|
||||
# Set the run user
|
||||
USER mastodon
|
||||
|
|
13
Gemfile
13
Gemfile
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby '>= 2.7.0', '< 3.3.0'
|
||||
ruby '>= 3.0.0'
|
||||
|
||||
gem 'pkg-config', '~> 1.5'
|
||||
|
||||
|
@ -9,10 +9,10 @@ gem 'puma', '~> 6.2'
|
|||
gem 'rails', '~> 6.1.7'
|
||||
gem 'sprockets', '~> 3.7.2'
|
||||
gem 'thor', '~> 1.2'
|
||||
gem 'rack', '~> 2.2.6'
|
||||
gem 'rack', '~> 2.2.7'
|
||||
|
||||
gem 'haml-rails', '~>2.0'
|
||||
gem 'pg', '~> 1.4'
|
||||
gem 'pg', '~> 1.5'
|
||||
gem 'makara', '~> 0.5'
|
||||
gem 'pghero'
|
||||
gem 'dotenv-rails', '~> 2.8'
|
||||
|
@ -30,7 +30,7 @@ gem 'browser'
|
|||
gem 'charlock_holmes', '~> 0.7.7'
|
||||
gem 'chewy', '~> 7.3'
|
||||
gem 'devise', '~> 4.9'
|
||||
gem 'devise-two-factor', '~> 4.0'
|
||||
gem 'devise-two-factor', '~> 4.1'
|
||||
|
||||
group :pam_authentication, optional: true do
|
||||
gem 'devise_pam_authenticatable2', '~> 9.2'
|
||||
|
@ -76,7 +76,7 @@ gem 'redcarpet', '~> 3.6'
|
|||
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||
gem 'rqrcode', '~> 2.1'
|
||||
gem 'ruby-progressbar', '~> 1.11'
|
||||
gem 'ruby-progressbar', '~> 1.13'
|
||||
gem 'sanitize', '~> 6.0'
|
||||
gem 'scenic', '~> 1.7'
|
||||
gem 'sidekiq', '~> 6.5'
|
||||
|
@ -121,7 +121,7 @@ group :test do
|
|||
gem 'capybara', '~> 3.39'
|
||||
gem 'climate_control'
|
||||
gem 'faker', '~> 3.2'
|
||||
gem 'json-schema', '~> 3.0'
|
||||
gem 'json-schema', '~> 4.0'
|
||||
gem 'rack-test', '~> 2.1'
|
||||
gem 'rails-controller-testing', '~> 1.0'
|
||||
gem 'rspec_junit_formatter', '~> 0.6'
|
||||
|
@ -163,3 +163,4 @@ gem 'hcaptcha', '~> 7.1'
|
|||
gem 'cocoon', '~> 1.2'
|
||||
|
||||
gem 'net-http', '~> 0.3.2'
|
||||
gem 'rubyzip', '~> 2.3'
|
||||
|
|
86
Gemfile.lock
86
Gemfile.lock
|
@ -104,12 +104,12 @@ GEM
|
|||
activerecord (>= 3.2, < 8.0)
|
||||
rake (>= 10.4, < 14.0)
|
||||
ast (2.4.2)
|
||||
attr_encrypted (3.1.0)
|
||||
attr_encrypted (4.0.0)
|
||||
encryptor (~> 3.0.0)
|
||||
attr_required (1.0.1)
|
||||
awrence (1.2.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.743.0)
|
||||
aws-partitions (1.752.0)
|
||||
aws-sdk-core (3.171.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
|
@ -118,7 +118,7 @@ GEM
|
|||
aws-sdk-kms (1.63.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.120.1)
|
||||
aws-sdk-s3 (1.121.0)
|
||||
aws-sdk-core (~> 3, >= 3.165.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.4)
|
||||
|
@ -142,7 +142,7 @@ GEM
|
|||
blurhash (0.1.7)
|
||||
bootsnap (1.16.0)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (5.4.0)
|
||||
brakeman (5.4.1)
|
||||
browser (5.3.1)
|
||||
brpoplpush-redis_script (0.1.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||
|
@ -156,7 +156,7 @@ GEM
|
|||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (>= 1.9.0)
|
||||
capistrano-bundler (2.0.1)
|
||||
capistrano-bundler (2.1.0)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-rails (1.6.2)
|
||||
capistrano (~> 3.1)
|
||||
|
@ -179,7 +179,7 @@ GEM
|
|||
activesupport
|
||||
cbor (0.5.9.6)
|
||||
charlock_holmes (0.7.7)
|
||||
chewy (7.3.0)
|
||||
chewy (7.3.2)
|
||||
activesupport (>= 5.2)
|
||||
elasticsearch (>= 7.12.0, < 7.14.0)
|
||||
elasticsearch-dsl
|
||||
|
@ -189,26 +189,26 @@ GEM
|
|||
coderay (1.1.3)
|
||||
color_diff (0.1)
|
||||
concurrent-ruby (1.2.2)
|
||||
connection_pool (2.3.0)
|
||||
connection_pool (2.4.0)
|
||||
cose (1.3.0)
|
||||
cbor (~> 0.5.9)
|
||||
openssl-signature_algorithm (~> 1.0)
|
||||
crack (0.4.5)
|
||||
rexml
|
||||
crass (1.0.6)
|
||||
css_parser (1.12.0)
|
||||
css_parser (1.14.0)
|
||||
addressable
|
||||
date (3.3.3)
|
||||
debug_inspector (1.0.0)
|
||||
debug_inspector (1.1.0)
|
||||
devise (4.9.2)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (4.0.2)
|
||||
devise-two-factor (4.1.0)
|
||||
activesupport (< 7.1)
|
||||
attr_encrypted (>= 1.3, < 4, != 2)
|
||||
attr_encrypted (>= 1.3, < 5, != 2)
|
||||
devise (~> 4.0)
|
||||
railties (< 7.1)
|
||||
rotp (~> 6.0)
|
||||
|
@ -241,7 +241,7 @@ GEM
|
|||
erubi (1.12.0)
|
||||
et-orbi (1.2.7)
|
||||
tzinfo
|
||||
excon (0.95.0)
|
||||
excon (0.99.0)
|
||||
fabrication (2.30.0)
|
||||
faker (3.2.0)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
|
@ -315,7 +315,7 @@ GEM
|
|||
hashie (5.0.0)
|
||||
hcaptcha (7.1.0)
|
||||
json
|
||||
highline (2.0.3)
|
||||
highline (2.1.0)
|
||||
hiredis (0.6.3)
|
||||
hkdf (0.3.0)
|
||||
htmlentities (4.3.4)
|
||||
|
@ -349,15 +349,15 @@ GEM
|
|||
ipaddress (0.8.3)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
json-canonicalization (0.3.1)
|
||||
json-canonicalization (0.3.2)
|
||||
json-jwt (1.15.3)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
httpclient
|
||||
json-ld (3.2.4)
|
||||
json-ld (3.2.5)
|
||||
htmlentities (~> 4.3)
|
||||
json-canonicalization (~> 0.3)
|
||||
json-canonicalization (~> 0.3, >= 0.3.2)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
multi_json (~> 1.15)
|
||||
rack (>= 2.2, < 4)
|
||||
|
@ -365,7 +365,7 @@ GEM
|
|||
json-ld-preloaded (3.2.2)
|
||||
json-ld (~> 3.2)
|
||||
rdf (~> 3.2)
|
||||
json-schema (3.0.0)
|
||||
json-schema (4.0.0)
|
||||
addressable (>= 2.8)
|
||||
jsonapi-renderer (0.2.2)
|
||||
jwt (2.7.0)
|
||||
|
@ -381,8 +381,8 @@ GEM
|
|||
activerecord
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-core (1.2.2)
|
||||
launchy (2.5.0)
|
||||
addressable (~> 2.7)
|
||||
launchy (2.5.2)
|
||||
addressable (~> 2.8)
|
||||
letter_opener (1.8.1)
|
||||
launchy (>= 2.2, < 3)
|
||||
letter_opener_web (2.0.0)
|
||||
|
@ -417,11 +417,11 @@ GEM
|
|||
method_source (1.0.0)
|
||||
mime-types (3.4.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2022.0105)
|
||||
mime-types-data (3.2023.0218.1)
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.8.1)
|
||||
minitest (5.18.0)
|
||||
msgpack (1.6.0)
|
||||
msgpack (1.7.0)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.3.0)
|
||||
net-http (0.3.2)
|
||||
|
@ -438,7 +438,7 @@ GEM
|
|||
net-ssh (>= 2.6.5, < 8.0.0)
|
||||
net-smtp (0.3.3)
|
||||
net-protocol
|
||||
net-ssh (7.0.1)
|
||||
net-ssh (7.1.0)
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.14.3)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
|
@ -481,18 +481,18 @@ GEM
|
|||
openssl (> 2.0)
|
||||
orm_adapter (0.5.0)
|
||||
ox (2.14.16)
|
||||
parallel (1.22.1)
|
||||
parser (3.2.2.0)
|
||||
parallel (1.23.0)
|
||||
parser (3.2.2.1)
|
||||
ast (~> 2.4.1)
|
||||
parslet (2.0.0)
|
||||
pastel (0.8.0)
|
||||
tty-color (~> 0.5)
|
||||
pg (1.4.6)
|
||||
pghero (3.3.2)
|
||||
pg (1.5.3)
|
||||
pghero (3.3.3)
|
||||
activerecord (>= 6)
|
||||
pkg-config (1.5.1)
|
||||
posix-spawn (0.3.15)
|
||||
premailer (1.18.0)
|
||||
premailer (1.21.0)
|
||||
addressable
|
||||
css_parser (>= 1.12.0)
|
||||
htmlentities (>= 4.0.0)
|
||||
|
@ -502,13 +502,13 @@ GEM
|
|||
premailer (~> 1.7, >= 1.7.9)
|
||||
private_address_check (0.5.0)
|
||||
public_suffix (5.0.1)
|
||||
puma (6.2.1)
|
||||
puma (6.2.2)
|
||||
nio4r (~> 2.0)
|
||||
pundit (2.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
raabro (1.4.0)
|
||||
racc (1.6.2)
|
||||
rack (2.2.6.4)
|
||||
rack (2.2.7)
|
||||
rack-attack (6.6.1)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-cors (2.0.1)
|
||||
|
@ -568,25 +568,25 @@ GEM
|
|||
redis (>= 4)
|
||||
redlock (1.3.2)
|
||||
redis (>= 3.0.0, < 6.0)
|
||||
regexp_parser (2.7.0)
|
||||
regexp_parser (2.8.0)
|
||||
request_store (1.5.1)
|
||||
rack (>= 1.4)
|
||||
responders (3.1.0)
|
||||
actionpack (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rexml (3.2.5)
|
||||
rotp (6.2.0)
|
||||
rotp (6.2.2)
|
||||
rpam2 (4.0.2)
|
||||
rqrcode (2.1.2)
|
||||
chunky_png (~> 1.0)
|
||||
rqrcode_core (~> 1.0)
|
||||
rqrcode_core (1.2.0)
|
||||
rspec-core (3.12.1)
|
||||
rspec-core (3.12.2)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-expectations (3.12.2)
|
||||
rspec-expectations (3.12.3)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-mocks (3.12.3)
|
||||
rspec-mocks (3.12.5)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-rails (6.0.1)
|
||||
|
@ -604,7 +604,7 @@ GEM
|
|||
rspec_chunked (0.6)
|
||||
rspec_junit_formatter (0.6.0)
|
||||
rspec-core (>= 2, < 4, != 2.12.0)
|
||||
rubocop (1.49.0)
|
||||
rubocop (1.50.2)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.2.0.0)
|
||||
|
@ -616,12 +616,12 @@ GEM
|
|||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.28.0)
|
||||
parser (>= 3.2.1.0)
|
||||
rubocop-capybara (2.17.1)
|
||||
rubocop-capybara (2.18.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-performance (1.17.1)
|
||||
rubocop (>= 1.7.0, < 2.0)
|
||||
rubocop-ast (>= 0.4.0)
|
||||
rubocop-rails (2.18.0)
|
||||
rubocop-rails (2.19.1)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
|
@ -633,6 +633,7 @@ GEM
|
|||
nokogiri (>= 1.10.5)
|
||||
rexml
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
rufus-scheduler (3.8.2)
|
||||
fugit (~> 1.1, >= 1.1.6)
|
||||
safety_net_attestation (0.4.0)
|
||||
|
@ -793,7 +794,7 @@ DEPENDENCIES
|
|||
concurrent-ruby
|
||||
connection_pool
|
||||
devise (~> 4.9)
|
||||
devise-two-factor (~> 4.0)
|
||||
devise-two-factor (~> 4.1)
|
||||
devise_pam_authenticatable2 (~> 9.2)
|
||||
discard (~> 1.2)
|
||||
doorkeeper (~> 5.6)
|
||||
|
@ -819,7 +820,7 @@ DEPENDENCIES
|
|||
idn-ruby
|
||||
json-ld
|
||||
json-ld-preloaded (~> 3.2)
|
||||
json-schema (~> 3.0)
|
||||
json-schema (~> 4.0)
|
||||
kaminari (~> 1.2)
|
||||
kt-paperclip (~> 7.1)!
|
||||
letter_opener (~> 1.8)
|
||||
|
@ -842,7 +843,7 @@ DEPENDENCIES
|
|||
omniauth_openid_connect (~> 0.6.1)
|
||||
ox (~> 2.14)
|
||||
parslet
|
||||
pg (~> 1.4)
|
||||
pg (~> 1.5)
|
||||
pghero
|
||||
pkg-config (~> 1.5)
|
||||
posix-spawn
|
||||
|
@ -851,7 +852,7 @@ DEPENDENCIES
|
|||
public_suffix (~> 5.0)
|
||||
puma (~> 6.2)
|
||||
pundit (~> 2.3)
|
||||
rack (~> 2.2.6)
|
||||
rack (~> 2.2.7)
|
||||
rack-attack (~> 6.6)
|
||||
rack-cors (~> 2.0)
|
||||
rack-test (~> 2.1)
|
||||
|
@ -873,7 +874,8 @@ DEPENDENCIES
|
|||
rubocop-performance
|
||||
rubocop-rails
|
||||
rubocop-rspec
|
||||
ruby-progressbar (~> 1.11)
|
||||
ruby-progressbar (~> 1.13)
|
||||
rubyzip (~> 2.3)
|
||||
sanitize (~> 6.0)
|
||||
scenic (~> 1.7)
|
||||
sidekiq (~> 6.5)
|
||||
|
|
|
@ -8,7 +8,7 @@ class AboutController < ApplicationController
|
|||
before_action :set_instance_presenter
|
||||
|
||||
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
|
||||
|
||||
private
|
||||
|
|
|
@ -7,8 +7,9 @@ class AccountsController < ApplicationController
|
|||
include AccountControllerConcern
|
||||
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 :set_cache_headers
|
||||
|
||||
skip_around_action :set_locale, if: -> { [:json, :rss].include?(request.format&.to_sym) }
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
@ -16,7 +17,7 @@ class AccountsController < ApplicationController
|
|||
def show
|
||||
respond_to do |format|
|
||||
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
|
||||
end
|
||||
|
|
|
@ -7,10 +7,6 @@ class ActivityPub::BaseController < Api::BaseController
|
|||
|
||||
private
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = 'Signature' if authorized_fetch_mode?
|
||||
end
|
||||
|
||||
def skip_temporary_suspension_response?
|
||||
false
|
||||
end
|
||||
|
|
|
@ -4,11 +4,12 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_items
|
||||
before_action :set_size
|
||||
before_action :set_type
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
expires_in 3.minutes, public: public_fetch_mode?
|
||||
|
|
|
@ -4,9 +4,10 @@ class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseContro
|
|||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!
|
||||
before_action :set_items
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
expires_in 0, public: false
|
||||
|
|
|
@ -6,9 +6,10 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_statuses
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
if page_requested?
|
||||
|
@ -16,6 +17,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
else
|
||||
expires_in(3.minutes, public: public_fetch_mode?)
|
||||
end
|
||||
|
||||
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
|
||||
|
@ -80,8 +82,4 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
def set_account
|
||||
@account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = 'Signature' if authorized_fetch_mode? || page_requested?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,9 +7,10 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
|||
|
||||
DESCENDANTS_LIMIT = 60
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_status
|
||||
before_action :set_cache_headers
|
||||
before_action :set_replies
|
||||
|
||||
def index
|
||||
|
|
|
@ -14,6 +14,10 @@ class Admin::AnnouncementsController < Admin::BaseController
|
|||
@announcement = Announcement.new
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize :announcement, :update?
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :announcement, :create?
|
||||
|
||||
|
@ -28,10 +32,6 @@ class Admin::AnnouncementsController < Admin::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize :announcement, :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize :announcement, :update?
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ module Admin
|
|||
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
after_action :verify_authorized
|
||||
|
||||
private
|
||||
|
@ -21,6 +23,10 @@ module Admin
|
|||
use_pack 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def set_user
|
||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
|
|
@ -33,7 +33,7 @@ module Admin
|
|||
|
||||
if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block)
|
||||
@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)
|
||||
render :new
|
||||
else
|
||||
|
|
|
@ -16,6 +16,10 @@ module Admin
|
|||
@role = UserRole.new
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @role, :update?
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :user_role, :create?
|
||||
|
||||
|
@ -30,10 +34,6 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @role, :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @role, :update?
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@ module Admin
|
|||
@rule = Rule.new
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @rule, :update?
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :rule, :create?
|
||||
|
||||
|
@ -24,10 +28,6 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @rule, :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @rule, :update?
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@ module Admin
|
|||
@warning_preset = AccountWarningPreset.new
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @warning_preset, :update?
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :account_warning_preset, :create?
|
||||
|
||||
|
@ -24,10 +28,6 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @warning_preset, :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @warning_preset, :update?
|
||||
|
||||
|
|
|
@ -10,12 +10,20 @@ module Admin
|
|||
@webhooks = Webhook.page(params[:page])
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @webhook, :show?
|
||||
end
|
||||
|
||||
def new
|
||||
authorize :webhook, :create?
|
||||
|
||||
@webhook = Webhook.new
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @webhook, :update?
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :webhook, :create?
|
||||
|
||||
|
@ -28,14 +36,6 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @webhook, :show?
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize @webhook, :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @webhook, :update?
|
||||
|
||||
|
|
|
@ -6,13 +6,14 @@ class Api::BaseController < ApplicationController
|
|||
|
||||
include RateLimitHeaders
|
||||
include AccessTokenTrackingConcern
|
||||
include ApiCachingConcern
|
||||
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
||||
before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access?
|
||||
before_action :require_not_suspended!
|
||||
before_action :set_cache_headers
|
||||
|
||||
vary_by 'Authorization'
|
||||
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
|
@ -148,10 +149,6 @@ class Api::BaseController < ApplicationController
|
|||
doorkeeper_authorize!(*scopes) if doorkeeper_token
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
end
|
||||
|
||||
def disallow_unauthenticated_api_access?
|
||||
ENV['DISALLOW_UNAUTHENTICATED_API_ACCESS'] == 'true' || Rails.configuration.x.whitelist_mode
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
|
|||
after_action :insert_pagination_headers
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
@accounts = load_accounts
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
|
|||
after_action :insert_pagination_headers
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
@accounts = load_accounts
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ class Api::V1::Accounts::LookupController < Api::BaseController
|
|||
before_action :set_account
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @account, serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
|||
after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) }
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
@statuses = load_statuses
|
||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
||||
end
|
||||
|
|
|
@ -18,6 +18,7 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
override_rate_limit_headers :follow, family: :follows
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @account, serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -16,6 +16,16 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
|||
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
def index
|
||||
authorize :domain_allow, :index?
|
||||
render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @domain_allow, :show?
|
||||
render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :domain_allow, :create?
|
||||
|
||||
|
@ -29,16 +39,6 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
|||
render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
|
||||
end
|
||||
|
||||
def index
|
||||
authorize :domain_allow, :index?
|
||||
render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @domain_allow, :show?
|
||||
render json: @domain_allow, serializer: REST::Admin::DomainAllowSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @domain_allow, :destroy?
|
||||
UnallowDomainService.new.call(@domain_allow)
|
||||
|
|
|
@ -16,6 +16,16 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
|||
|
||||
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
|
||||
authorize :domain_block, :create?
|
||||
|
||||
|
@ -28,16 +38,6 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
|||
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
|
||||
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
|
||||
authorize @domain_block, :update?
|
||||
@domain_block.update!(domain_block_params)
|
||||
|
|
|
@ -18,15 +18,6 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController
|
|||
limit
|
||||
).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
|
||||
authorize :email_domain_block, :index?
|
||||
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
|
||||
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
|
||||
authorize @email_domain_block, :destroy?
|
||||
@email_domain_block.destroy!
|
||||
|
|
|
@ -18,13 +18,6 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController
|
|||
limit
|
||||
).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
|
||||
authorize :ip_block, :index?
|
||||
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
|
||||
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
|
||||
authorize @ip_block, :update?
|
||||
@ip_block.update(resource_params)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::CustomEmojisController < Api::BaseController
|
||||
skip_before_action :set_cache_headers
|
||||
vary_by '', unless: :disallow_unauthenticated_api_access?
|
||||
|
||||
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) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ class Api::V1::DirectoriesController < Api::BaseController
|
|||
before_action :set_accounts
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@ class Api::V1::FiltersController < Api::BaseController
|
|||
render json: @filters, each_serializer: REST::V1::FilterSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @filter, serializer: REST::V1::FilterSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
ApplicationRecord.transaction do
|
||||
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
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @filter, serializer: REST::V1::FilterSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
ApplicationRecord.transaction do
|
||||
@filter.update!(keyword_params)
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
class Api::V1::Instances::ActivityController < Api::BaseController
|
||||
before_action :require_enabled_api!
|
||||
|
||||
skip_before_action :set_cache_headers
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
|
||||
vary_by ''
|
||||
|
||||
def show
|
||||
expires_in 1.day, public: true
|
||||
cache_even_if_authenticated!
|
||||
render_with_cache json: :activity, expires_in: 1.day
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,15 @@ class Api::V1::Instances::DomainBlocksController < Api::BaseController
|
|||
before_action :require_enabled_api!
|
||||
before_action :set_domain_blocks
|
||||
|
||||
vary_by '', if: -> { Setting.show_domain_blocks == 'all' }
|
||||
|
||||
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?))
|
||||
end
|
||||
|
||||
|
|
|
@ -2,11 +2,19 @@
|
|||
|
||||
class Api::V1::Instances::ExtendedDescriptionsController < Api::BaseController
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
skip_around_action :set_locale
|
||||
|
||||
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
|
||||
expires_in 3.minutes, public: true
|
||||
cache_even_if_authenticated!
|
||||
render json: @extended_description, serializer: REST::ExtendedDescriptionSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -3,11 +3,18 @@
|
|||
class Api::V1::Instances::PeersController < Api::BaseController
|
||||
before_action :require_enabled_api!
|
||||
|
||||
skip_before_action :set_cache_headers
|
||||
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
|
||||
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) }
|
||||
end
|
||||
|
||||
|
|
|
@ -5,8 +5,10 @@ class Api::V1::Instances::PrivacyPoliciesController < Api::BaseController
|
|||
|
||||
before_action :set_privacy_policy
|
||||
|
||||
vary_by ''
|
||||
|
||||
def show
|
||||
expires_in 1.day, public: true
|
||||
cache_even_if_authenticated!
|
||||
render json: @privacy_policy, serializer: REST::PrivacyPolicySerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -2,10 +2,19 @@
|
|||
|
||||
class Api::V1::Instances::RulesController < Api::BaseController
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
skip_around_action :set_locale
|
||||
|
||||
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
|
||||
cache_even_if_authenticated!
|
||||
render json: @rules, each_serializer: REST::RuleSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -5,8 +5,10 @@ class Api::V1::Instances::TranslationLanguagesController < Api::BaseController
|
|||
|
||||
before_action :set_languages
|
||||
|
||||
vary_by ''
|
||||
|
||||
def show
|
||||
expires_in 1.day, public: true
|
||||
cache_even_if_authenticated!
|
||||
render json: @languages
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::InstancesController < Api::BaseController
|
||||
skip_before_action :set_cache_headers
|
||||
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
|
||||
expires_in 3.minutes, public: true
|
||||
cache_even_if_authenticated!
|
||||
render_with_cache json: InstancePresenter.new, serializer: REST::V1::InstanceSerializer, root: 'instance'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,19 +6,20 @@ class Api::V1::MediaController < Api::BaseController
|
|||
before_action :set_media_attachment, 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
|
||||
@media_attachment = current_account.media_attachments.create!(media_attachment_params)
|
||||
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer
|
||||
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
|
||||
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
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
|
||||
end
|
||||
|
||||
def update
|
||||
@media_attachment.update!(updateable_media_attachment_params)
|
||||
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
|
||||
|
|
|
@ -8,6 +8,7 @@ class Api::V1::PollsController < Api::BaseController
|
|||
before_action :refresh_poll
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @poll, serializer: REST::PollSerializer, include_results: true
|
||||
end
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
|
|||
before_action :set_push_subscription
|
||||
before_action :check_push_subscription, only: [:show, :update]
|
||||
|
||||
def show
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
@push_subscription&.destroy!
|
||||
|
||||
|
@ -21,10 +25,6 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
|
|||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@push_subscription.update!(data: data_params)
|
||||
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||
|
|
|
@ -8,6 +8,7 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
|
|||
after_action :insert_pagination_headers
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
@accounts = load_accounts
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ class Api::V1::Statuses::HistoriesController < Api::BaseController
|
|||
before_action :set_status
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @status.edits.includes(:account, status: [:account]), each_serializer: REST::StatusEditSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
|
|||
after_action :insert_pagination_headers
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
@accounts = load_accounts
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
|
|
@ -24,11 +24,14 @@ class Api::V1::StatusesController < Api::BaseController
|
|||
DESCENDANTS_DEPTH_LIMIT = 20
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
@status = cache_collection([@status], Status).first
|
||||
render json: @status, serializer: REST::StatusSerializer
|
||||
end
|
||||
|
||||
def context
|
||||
cache_if_unauthenticated!
|
||||
|
||||
ancestors_limit = CONTEXT_LIMIT
|
||||
descendants_limit = CONTEXT_LIMIT
|
||||
descendants_depth_limit = nil
|
||||
|
|
|
@ -8,6 +8,7 @@ class Api::V1::TagsController < Api::BaseController
|
|||
override_rate_limit_headers :follow, family: :follows
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
render json: @tag, serializer: REST::TagSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
|||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
@statuses = load_statuses
|
||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
|||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||
|
||||
def show
|
||||
cache_if_unauthenticated!
|
||||
@statuses = load_statuses
|
||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
||||
end
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Trends::LinksController < Api::BaseController
|
||||
vary_by 'Authorization, Accept-Language'
|
||||
|
||||
before_action :set_links
|
||||
|
||||
after_action :insert_pagination_headers
|
||||
|
@ -8,6 +10,7 @@ class Api::V1::Trends::LinksController < Api::BaseController
|
|||
DEFAULT_LINKS_LIMIT = 10
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
render json: @links, each_serializer: REST::Trends::LinkSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Trends::StatusesController < Api::BaseController
|
||||
vary_by 'Authorization, Accept-Language'
|
||||
|
||||
before_action :set_statuses
|
||||
|
||||
after_action :insert_pagination_headers
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
render json: @statuses, each_serializer: REST::StatusSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ class Api::V1::Trends::TagsController < Api::BaseController
|
|||
DEFAULT_TAGS_LIMIT = (ENV['MAX_TRENDING_TAGS'] || 10).to_i
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
render json: @tags, each_serializer: REST::TagSerializer, relationships: TagRelationshipsPresenter.new(@tags, current_user&.account_id)
|
||||
end
|
||||
|
||||
|
|
|
@ -12,13 +12,13 @@ class Api::V2::Filters::KeywordsController < Api::BaseController
|
|||
render json: @keywords, each_serializer: REST::FilterKeywordSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
@keyword = current_account.custom_filters.find(params[:filter_id]).keywords.create!(resource_params)
|
||||
|
||||
def show
|
||||
render json: @keyword, serializer: REST::FilterKeywordSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
def create
|
||||
@keyword = current_account.custom_filters.find(params[:filter_id]).keywords.create!(resource_params)
|
||||
|
||||
render json: @keyword, serializer: REST::FilterKeywordSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -12,13 +12,13 @@ class Api::V2::Filters::StatusesController < Api::BaseController
|
|||
render json: @status_filters, each_serializer: REST::FilterStatusSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
@status_filter = current_account.custom_filters.find(params[:filter_id]).statuses.create!(resource_params)
|
||||
|
||||
def show
|
||||
render json: @status_filter, serializer: REST::FilterStatusSerializer
|
||||
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
|
||||
end
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@ class Api::V2::FiltersController < Api::BaseController
|
|||
render json: @filters, each_serializer: REST::FilterSerializer, rules_requested: true
|
||||
end
|
||||
|
||||
def create
|
||||
@filter = current_account.custom_filters.create!(resource_params)
|
||||
|
||||
def show
|
||||
render json: @filter, serializer: REST::FilterSerializer, rules_requested: true
|
||||
end
|
||||
|
||||
def show
|
||||
def create
|
||||
@filter = current_account.custom_filters.create!(resource_params)
|
||||
|
||||
render json: @filter, serializer: REST::FilterSerializer, rules_requested: true
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class Api::V2::InstancesController < Api::V1::InstancesController
|
||||
def show
|
||||
expires_in 3.minutes, public: true
|
||||
cache_even_if_authenticated!
|
||||
render_with_cache json: InstancePresenter.new, serializer: REST::InstanceSerializer, root: 'instance'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,8 @@ class Api::V2::MediaController < Api::V1::MediaController
|
|||
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: @media_attachment.not_processed? ? 202 : 200
|
||||
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,6 +21,8 @@ class ApplicationController < ActionController::Base
|
|||
helper_method :omniauth_only?
|
||||
helper_method :sso_account_settings
|
||||
helper_method :whitelist_mode?
|
||||
helper_method :body_class_string
|
||||
helper_method :skip_csrf_meta_tags?
|
||||
|
||||
rescue_from ActionController::ParameterMissing, Paperclip::AdapterRegistry::NoHandlerError, with: :bad_request
|
||||
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
||||
|
@ -37,9 +39,11 @@ class ApplicationController < ActionController::Base
|
|||
service_unavailable
|
||||
end
|
||||
|
||||
before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
|
||||
before_action :store_referrer, except: :raise_not_found, if: :devise_controller?
|
||||
before_action :require_functional!, if: :user_signed_in?
|
||||
|
||||
before_action :set_cache_control_defaults
|
||||
|
||||
skip_before_action :verify_authenticity_token, only: :raise_not_found
|
||||
|
||||
def raise_not_found
|
||||
|
@ -56,14 +60,25 @@ class ApplicationController < ActionController::Base
|
|||
!authorized_fetch_mode?
|
||||
end
|
||||
|
||||
def store_current_location
|
||||
store_location_for(:user, request.url) unless [:json, :rss].include?(request.format&.to_sym)
|
||||
def store_referrer
|
||||
return if request.referer.blank?
|
||||
|
||||
redirect_uri = URI(request.referer)
|
||||
return if redirect_uri.path.start_with?('/auth')
|
||||
|
||||
stored_url = redirect_uri.to_s if redirect_uri.host == request.host && redirect_uri.port == request.port
|
||||
|
||||
store_location_for(:user, stored_url)
|
||||
end
|
||||
|
||||
def require_functional!
|
||||
redirect_to edit_user_registration_path unless current_user.functional?
|
||||
end
|
||||
|
||||
def skip_csrf_meta_tags?
|
||||
false
|
||||
end
|
||||
|
||||
def after_sign_out_path_for(_resource_or_scope)
|
||||
if ENV['OMNIAUTH_ONLY'] == 'true' && ENV['OIDC_ENABLED'] == 'true'
|
||||
'/auth/auth/openid_connect/logout'
|
||||
|
@ -127,7 +142,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def sso_account_settings
|
||||
ENV.fetch('SSO_ACCOUNT_SETTINGS')
|
||||
ENV.fetch('SSO_ACCOUNT_SETTINGS', nil)
|
||||
end
|
||||
|
||||
def current_account
|
||||
|
@ -142,6 +157,10 @@ class ApplicationController < ActionController::Base
|
|||
@current_session = SessionActivation.find_by(session_id: cookies.signed['_session_id']) if cookies.signed['_session_id'].present?
|
||||
end
|
||||
|
||||
def body_class_string
|
||||
@body_classes || ''
|
||||
end
|
||||
|
||||
def respond_with_error(code)
|
||||
respond_to do |format|
|
||||
format.any do
|
||||
|
@ -151,4 +170,8 @@ class ApplicationController < ActionController::Base
|
|||
format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code }
|
||||
end
|
||||
end
|
||||
|
||||
def set_cache_control_defaults
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,16 +25,16 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
super(&:build_invite_request)
|
||||
end
|
||||
|
||||
def destroy
|
||||
not_found
|
||||
end
|
||||
|
||||
def update
|
||||
super do |resource|
|
||||
resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
not_found
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def update_resource(resource, params)
|
||||
|
@ -157,6 +157,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,7 +60,7 @@ class AuthorizeInteractionsController < ApplicationController
|
|||
end
|
||||
|
||||
def uri_param
|
||||
params[:uri] || params.fetch(:acct, '').gsub(/\Aacct:/, '')
|
||||
params[:uri] || params.fetch(:acct, '').delete_prefix('acct:')
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ApiCachingConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def cache_if_unauthenticated!
|
||||
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
|
||||
end
|
||||
|
||||
def cache_even_if_authenticated!
|
||||
expires_in(5.minutes, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless whitelist_mode?
|
||||
end
|
||||
end
|
|
@ -155,8 +155,30 @@ module CacheConcern
|
|||
end
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def vary_by(value, **kwargs)
|
||||
before_action(**kwargs) do |controller|
|
||||
response.headers['Vary'] = value.respond_to?(:call) ? controller.instance_exec(&value) : value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
included do
|
||||
after_action :enforce_cache_control!
|
||||
end
|
||||
|
||||
# Prevents high-entropy headers such as `Cookie`, `Signature` or `Authorization`
|
||||
# from being used as cache keys, while allowing to `Vary` on them (to not serve
|
||||
# anonymous cached data to authenticated requests when authentication matters)
|
||||
def enforce_cache_control!
|
||||
vary = response.headers['Vary']&.split&.map { |x| x.strip.downcase }
|
||||
return unless vary.present? && %w(cookie authorization signature).any? { |header| vary.include?(header) && request.headers[header].present? }
|
||||
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def render_with_cache(**options)
|
||||
raise ArgumentError, 'only JSON render calls are supported' unless options.key?(:json) || block_given?
|
||||
raise ArgumentError, 'Only JSON render calls are supported' unless options.key?(:json) || block_given?
|
||||
|
||||
key = options.delete(:key) || [[params[:controller], params[:action]].join('/'), options[:json].respond_to?(:cache_key) ? options[:json].cache_key : nil, options[:fields].nil? ? nil : options[:fields].join(',')].compact.join(':')
|
||||
expires_in = options.delete(:expires_in) || 3.minutes
|
||||
|
@ -176,10 +198,6 @@ module CacheConcern
|
|||
end
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = public_fetch_mode? ? 'Accept' : 'Accept, Signature'
|
||||
end
|
||||
|
||||
def cache_collection(raw, klass)
|
||||
return raw unless klass.respond_to?(:with_includes)
|
||||
|
||||
|
|
|
@ -180,14 +180,15 @@ module SignatureVerification
|
|||
|
||||
def build_signed_string
|
||||
signed_headers.map do |signed_header|
|
||||
if signed_header == Request::REQUEST_TARGET
|
||||
case signed_header
|
||||
when Request::REQUEST_TARGET
|
||||
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
||||
elsif signed_header == '(created)'
|
||||
when '(created)'
|
||||
raise SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019'
|
||||
raise SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank?
|
||||
|
||||
"(created): #{signature_params['created']}"
|
||||
elsif signed_header == '(expires)'
|
||||
when '(expires)'
|
||||
raise SignatureVerificationError, 'Invalid pseudo-header (expires) for rsa-sha256' unless signature_algorithm == 'hs2019'
|
||||
raise SignatureVerificationError, 'Pseudo-header (expires) used but corresponding argument missing' if signature_params['expires'].blank?
|
||||
|
||||
|
@ -244,7 +245,7 @@ module SignatureVerification
|
|||
end
|
||||
|
||||
if key_id.start_with?('acct:')
|
||||
stoplight_wrap_request { ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, ''), suppress_errors: false) }
|
||||
stoplight_wrap_request { ResolveAccountService.new.call(key_id.delete_prefix('acct:'), suppress_errors: false) }
|
||||
elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
|
||||
account = ActivityPub::TagManager.instance.uri_to_actor(key_id)
|
||||
account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false, suppress_errors: false) }
|
||||
|
|
|
@ -7,6 +7,12 @@ module WebAppControllerConcern
|
|||
prepend_before_action :redirect_unauthenticated_to_permalinks!
|
||||
before_action :set_pack
|
||||
before_action :set_app_body_class
|
||||
|
||||
vary_by 'Accept, Accept-Language, Cookie'
|
||||
end
|
||||
|
||||
def skip_csrf_meta_tags?
|
||||
current_user.nil?
|
||||
end
|
||||
|
||||
def set_app_body_class
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CustomCssController < ApplicationController
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!
|
||||
skip_before_action :update_user_sign_in
|
||||
skip_before_action :set_session_activity
|
||||
|
||||
skip_around_action :set_locale
|
||||
|
||||
before_action :set_cache_headers
|
||||
|
||||
class CustomCssController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
def show
|
||||
expires_in 3.minutes, public: true
|
||||
request.session_options[:skip] = true
|
||||
render content_type: 'text/css'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ class Disputes::BaseController < ApplicationController
|
|||
before_action :set_body_classes
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
before_action :set_cache_headers
|
||||
|
||||
private
|
||||
|
||||
|
@ -20,4 +21,8 @@ class Disputes::BaseController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
class EmojisController < ApplicationController
|
||||
before_action :set_emoji
|
||||
before_action :set_cache_headers
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
expires_in 3.minutes, public: true
|
||||
render_with_cache json: @emoji, content_type: 'application/activity+json', serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ class Filters::StatusesController < ApplicationController
|
|||
before_action :set_status_filters
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
PER_PAGE = 20
|
||||
|
||||
|
@ -49,4 +50,8 @@ class Filters::StatusesController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ class FiltersController < ApplicationController
|
|||
before_action :set_filter, only: [:edit, :update, :destroy]
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
def index
|
||||
@filters = current_account.custom_filters.includes(:keywords, :statuses).order(:phrase)
|
||||
|
@ -17,6 +18,8 @@ class FiltersController < ApplicationController
|
|||
@filter.keywords.build
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def create
|
||||
@filter = current_account.custom_filters.build(resource_params)
|
||||
|
||||
|
@ -27,8 +30,6 @@ class FiltersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
if @filter.update(resource_params)
|
||||
redirect_to filters_path
|
||||
|
@ -59,4 +60,8 @@ class FiltersController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,8 +5,9 @@ class FollowerAccountsController < ApplicationController
|
|||
include SignatureVerification
|
||||
include WebAppControllerConcern
|
||||
|
||||
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 :set_cache_headers
|
||||
|
||||
skip_around_action :set_locale, if: -> { request.format == :json }
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
@ -14,7 +15,7 @@ class FollowerAccountsController < ApplicationController
|
|||
def index
|
||||
respond_to do |format|
|
||||
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?
|
||||
end
|
||||
|
||||
format.json do
|
||||
|
|
|
@ -5,8 +5,9 @@ class FollowingAccountsController < ApplicationController
|
|||
include SignatureVerification
|
||||
include WebAppControllerConcern
|
||||
|
||||
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 :set_cache_headers
|
||||
|
||||
skip_around_action :set_locale, if: -> { request.format == :json }
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
@ -14,7 +15,7 @@ class FollowingAccountsController < ApplicationController
|
|||
def index
|
||||
respond_to do |format|
|
||||
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?
|
||||
end
|
||||
|
||||
format.json do
|
||||
|
|
|
@ -6,7 +6,7 @@ class HomeController < ApplicationController
|
|||
before_action :set_instance_presenter
|
||||
|
||||
def index
|
||||
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
|
||||
|
||||
private
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class InstanceActorsController < ApplicationController
|
||||
include AccountControllerConcern
|
||||
class InstanceActorsController < ActivityPub::BaseController
|
||||
vary_by ''
|
||||
|
||||
skip_before_action :check_account_confirmation
|
||||
skip_around_action :set_locale
|
||||
serialization_scope nil
|
||||
|
||||
before_action :set_account
|
||||
skip_before_action :require_functional!
|
||||
skip_before_action :update_user_sign_in
|
||||
|
||||
def show
|
||||
expires_in 10.minutes, public: true
|
||||
|
|
|
@ -9,7 +9,7 @@ class IntentsController < ApplicationController
|
|||
if uri.scheme == 'web+mastodon'
|
||||
case uri.host
|
||||
when 'follow'
|
||||
return redirect_to authorize_interaction_path(uri: uri.query_values['uri'].gsub(/\Aacct:/, ''))
|
||||
return redirect_to authorize_interaction_path(uri: uri.query_values['uri'].delete_prefix('acct:'))
|
||||
when 'share'
|
||||
return redirect_to share_path(text: uri.query_values['text'])
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ class InvitesController < ApplicationController
|
|||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
def index
|
||||
authorize :invite, :create?
|
||||
|
@ -54,4 +55,8 @@ class InvitesController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ManifestsController < ApplicationController
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!
|
||||
class ManifestsController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
# Prevent `active_model_serializer`'s `ActionController::Serialization` from calling `current_user`
|
||||
# and thus re-issuing session cookies
|
||||
serialization_scope nil
|
||||
|
||||
def show
|
||||
expires_in 3.minutes, public: true
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
class MediaController < ApplicationController
|
||||
include Authorization
|
||||
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
||||
before_action :authenticate_user!, if: :whitelist_mode?
|
||||
|
|
|
@ -6,7 +6,6 @@ class MediaProxyController < ApplicationController
|
|||
include Redisable
|
||||
include Lockable
|
||||
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!
|
||||
|
||||
before_action :authenticate_user!, if: :whitelist_mode?
|
||||
|
@ -17,7 +16,7 @@ class MediaProxyController < ApplicationController
|
|||
rescue_from HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, with: :internal_server_error
|
||||
|
||||
def show
|
||||
with_lock("media_download:#{params[:id]}") do
|
||||
with_redis_lock("media_download:#{params[:id]}") do
|
||||
@media_attachment = MediaAttachment.remote.attached.find(params[:id])
|
||||
authorize @media_attachment.status, :show?
|
||||
redownload! if @media_attachment.needs_redownload? && !reject_media?
|
||||
|
|
|
@ -39,6 +39,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
|||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
|||
before_action :set_pack
|
||||
before_action :require_not_suspended!, only: :destroy
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
skip_before_action :require_functional!
|
||||
|
||||
|
@ -35,4 +36,8 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
|||
def require_not_suspended!
|
||||
forbidden if current_account.suspended?
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ class PrivacyController < ApplicationController
|
|||
before_action :set_instance_presenter
|
||||
|
||||
def show
|
||||
expires_in 0, public: true if current_account.nil?
|
||||
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -8,6 +8,7 @@ class RelationshipsController < ApplicationController
|
|||
before_action :set_pack
|
||||
before_action :set_relationships, only: :show
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
|
||||
|
||||
|
@ -75,4 +76,8 @@ class RelationshipsController < ApplicationController
|
|||
def set_pack
|
||||
use_pack 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,6 +8,8 @@ class Settings::ApplicationsController < Settings::BaseController
|
|||
@applications = current_user.applications.order(id: :desc).page(params[:page])
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def new
|
||||
@application = Doorkeeper::Application.new(
|
||||
redirect_uri: Doorkeeper.configuration.native_redirect_uri,
|
||||
|
@ -15,8 +17,6 @@ class Settings::ApplicationsController < Settings::BaseController
|
|||
)
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def create
|
||||
@application = current_user.applications.build(application_params)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class Settings::BaseController < ApplicationController
|
|||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def require_not_suspended!
|
||||
|
|
|
@ -15,7 +15,7 @@ class Settings::ExportsController < Settings::BaseController
|
|||
def create
|
||||
backup = nil
|
||||
|
||||
with_lock("backup:#{current_user.id}") do
|
||||
with_redis_lock("backup:#{current_user.id}") do
|
||||
authorize :backup, :create?
|
||||
backup = current_user.backups.create!
|
||||
end
|
||||
|
|
|
@ -1,31 +1,97 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ImportsController < Settings::BaseController
|
||||
before_action :set_account
|
||||
require 'csv'
|
||||
|
||||
def show
|
||||
@import = Import.new
|
||||
class Settings::ImportsController < Settings::BaseController
|
||||
before_action :set_bulk_import, only: [:show, :confirm, :destroy]
|
||||
before_action :set_recent_imports, only: [:index]
|
||||
|
||||
TYPE_TO_FILENAME_MAP = {
|
||||
following: 'following_accounts_failures.csv',
|
||||
blocking: 'blocked_accounts_failures.csv',
|
||||
muting: 'muted_accounts_failures.csv',
|
||||
domain_blocking: 'blocked_domains_failures.csv',
|
||||
bookmarks: 'bookmarks_failures.csv',
|
||||
}.freeze
|
||||
|
||||
TYPE_TO_HEADERS_MAP = {
|
||||
following: ['Account address', 'Show boosts', 'Notify on new posts', 'Languages'],
|
||||
blocking: false,
|
||||
muting: ['Account address', 'Hide notifications'],
|
||||
domain_blocking: false,
|
||||
bookmarks: false,
|
||||
}.freeze
|
||||
|
||||
def index
|
||||
@import = Form::Import.new(current_account: current_account)
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def failures
|
||||
@bulk_import = current_account.bulk_imports.where(state: :finished).find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
format.csv do
|
||||
filename = TYPE_TO_FILENAME_MAP[@bulk_import.type.to_sym]
|
||||
headers = TYPE_TO_HEADERS_MAP[@bulk_import.type.to_sym]
|
||||
|
||||
export_data = CSV.generate(headers: headers, write_headers: true) do |csv|
|
||||
@bulk_import.rows.find_each do |row|
|
||||
case @bulk_import.type.to_sym
|
||||
when :following
|
||||
csv << [row.data['acct'], row.data.fetch('show_reblogs', true), row.data.fetch('notify', false), row.data['languages']&.join(', ')]
|
||||
when :blocking
|
||||
csv << [row.data['acct']]
|
||||
when :muting
|
||||
csv << [row.data['acct'], row.data.fetch('hide_notifications', true)]
|
||||
when :domain_blocking
|
||||
csv << [row.data['domain']]
|
||||
when :bookmarks
|
||||
csv << [row.data['uri']]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
send_data export_data, filename: filename
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def confirm
|
||||
@bulk_import.update!(state: :scheduled)
|
||||
BulkImportWorker.perform_async(@bulk_import.id)
|
||||
redirect_to settings_imports_path, notice: I18n.t('imports.success')
|
||||
end
|
||||
|
||||
def create
|
||||
@import = Import.new(import_params)
|
||||
@import.account = @account
|
||||
@import = Form::Import.new(import_params.merge(current_account: current_account))
|
||||
|
||||
if @import.save
|
||||
ImportWorker.perform_async(@import.id)
|
||||
redirect_to settings_import_path, notice: I18n.t('imports.success')
|
||||
redirect_to settings_import_path(@import.bulk_import.id)
|
||||
else
|
||||
render :show
|
||||
# We need to set recent imports as we are displaying the index again
|
||||
set_recent_imports
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@bulk_import.destroy!
|
||||
redirect_to settings_imports_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = current_user.account
|
||||
def import_params
|
||||
params.require(:form_import).permit(:data, :type, :mode)
|
||||
end
|
||||
|
||||
def import_params
|
||||
params.require(:import).permit(:data, :type, :mode)
|
||||
def set_bulk_import
|
||||
@bulk_import = current_account.bulk_imports.where(state: :unconfirmed).find(params[:id])
|
||||
end
|
||||
|
||||
def set_recent_imports
|
||||
@recent_imports = current_account.bulk_imports.reorder(id: :desc).limit(10)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::Preferences::AppearanceController < Settings::PreferencesController
|
||||
class Settings::Preferences::AppearanceController < Settings::Preferences::BaseController
|
||||
private
|
||||
|
||||
def after_update_redirect_path
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::PreferencesController < Settings::BaseController
|
||||
class Settings::Preferences::BaseController < Settings::BaseController
|
||||
def show; end
|
||||
|
||||
def update
|
||||
|
@ -15,7 +15,7 @@ class Settings::PreferencesController < Settings::BaseController
|
|||
private
|
||||
|
||||
def after_update_redirect_path
|
||||
settings_preferences_path
|
||||
raise 'Override in controller'
|
||||
end
|
||||
|
||||
def user_params
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::Preferences::NotificationsController < Settings::PreferencesController
|
||||
class Settings::Preferences::NotificationsController < Settings::Preferences::BaseController
|
||||
private
|
||||
|
||||
def after_update_redirect_path
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::Preferences::OtherController < Settings::PreferencesController
|
||||
class Settings::Preferences::OtherController < Settings::Preferences::BaseController
|
||||
private
|
||||
|
||||
def after_update_redirect_path
|
||||
|
|
|
@ -8,9 +8,8 @@ module Settings
|
|||
before_action :require_otp_enabled
|
||||
before_action :require_webauthn_enabled, only: [:index, :destroy]
|
||||
|
||||
def new; end
|
||||
|
||||
def index; end
|
||||
def new; end
|
||||
|
||||
def options
|
||||
current_user.update(webauthn_id: WebAuthn.generate_user_id) unless current_user.webauthn_id
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue