Compare commits
254 Commits
acf635ffe8
...
849d7bff51
Author | SHA1 | Date |
---|---|---|
Ariadne Conill | 849d7bff51 | |
Ariadne Conill | 00412e8037 | |
Claire | f08f6d20e6 | |
Renaud Chaput | ea04f33f50 | |
fusagiko / takayamaki | 3d9e35375c | |
Renaud Chaput | a33d6c946a | |
fusagiko / takayamaki | e8243d5bbd | |
Claire | 5f0d2b6e3b | |
Claire | f3af434c25 | |
fusagiko / takayamaki | f4e3e309b1 | |
Eugen Rochko | bbd0e9caa6 | |
Claire | a8939e9098 | |
Claire | 10f5329ddf | |
fusagiko / takayamaki | 9ab89bb832 | |
fusagiko / takayamaki | 20f1f3aa7d | |
Claire | 8b31030fe4 | |
Claire | d77fbbed73 | |
Claire | f89f3a8566 | |
Claire | 61f3e0e95e | |
Eugen Rochko | 8bf9bd5ac8 | |
Eugen Rochko | 75e28731a5 | |
fusagiko / takayamaki | aff2d55b80 | |
fusagiko / takayamaki | a49707dacb | |
Eugen Rochko | 7835f8fd22 | |
Claire | e9eab013e7 | |
Nick Schonning | 51479f5c28 | |
Christian Schmidt | 09054f5485 | |
Claire | 2d029dedd9 | |
Claire | 5d18840ab9 | |
Claire | 16c5354b8c | |
Claire | de74acbe0c | |
Claire | ed0a407888 | |
Plastikmensch | 179e38cf15 | |
Claire | 3fb7fe14c6 | |
Claire | 9b59748679 | |
Claire | 6f64c79ca4 | |
Claire | a6207d243b | |
Matt Jankowski | f877aa9d70 | |
Claire | 746979f75d | |
Tim Campbell | f258478395 | |
mogaminsk | c9e040fb24 | |
S.H | 5811ccc611 | |
zunda | c0ea33e3fc | |
Nick Schonning | e675c10d19 | |
Tim Campbell | ac41a9712e | |
Daniel M Brasil | c9210af3ee | |
dependabot[bot] | 64fae0efb5 | |
Matt Jankowski | 0b249ebdb0 | |
Renaud Chaput | 830e6cefae | |
Nick Schonning | 569b39256b | |
dependabot[bot] | 880e661d53 | |
dependabot[bot] | ff974395c2 | |
dependabot[bot] | 849d93e50a | |
Claire | c3c7d59072 | |
Nick Schonning | f95125bd04 | |
Florin | 27bafabb64 | |
Nick Schonning | e1ebcc007d | |
Nick Schonning | ff3b7069cf | |
Nick Schonning | da3bd913ae | |
Nick Schonning | d5a185d721 | |
Nick Schonning | 1fe04f740a | |
Matt Jankowski | c97b611b6b | |
Matt Jankowski | 710745e16b | |
Matt Jankowski | cf18cc2891 | |
Matt Jankowski | bdcd8a9e88 | |
Matt Jankowski | 08fb9d300a | |
Matt Jankowski | 2c6c398c60 | |
Matt Jankowski | a1cca1c8b6 | |
Matt Jankowski | d9a958fcf7 | |
Nick Schonning | b25860c509 | |
Claire | a2a22bad23 | |
Claire | 1e75eb690d | |
Renaud Chaput | 45579a26cf | |
fusagiko / takayamaki | 0999cb4601 | |
Claire | c98b012583 | |
Renaud Chaput | 9a52a7f7a0 | |
fusagiko / takayamaki | e38b391940 | |
dependabot[bot] | 9b8cb947a7 | |
Matt Jankowski | 3df665fd23 | |
Claire | 8b636a29c6 | |
Matt Jankowski | a0c9f2447e | |
Matt Jankowski | 97385f27bd | |
Claire | 9c1929efad | |
Claire | d37c0a1060 | |
Matt Jankowski | 668a19a2f3 | |
Matt Jankowski | 05e3abe9d9 | |
dependabot[bot] | 8d61d2b0da | |
dependabot[bot] | 8f7c172eb8 | |
dependabot[bot] | b0ebaeb691 | |
dependabot[bot] | 1d49718a84 | |
dependabot[bot] | 14a7e414fc | |
fusagiko / takayamaki | 8227af8dcc | |
dependabot[bot] | 2839fbc733 | |
dependabot[bot] | 4acf5f8971 | |
dependabot[bot] | 4b87e2a8db | |
dependabot[bot] | b75c353962 | |
dependabot[bot] | 18f58f4284 | |
Matt Jankowski | 24491abf6d | |
Matt Jankowski | b5c4b47746 | |
Matt Jankowski | 38b2974a83 | |
Matt Jankowski | f1c1dd0118 | |
Matt Jankowski | a7df578f97 | |
dependabot[bot] | c26b1b0a1c | |
dependabot[bot] | 389f0443c8 | |
Matt Jankowski | 570079f8ce | |
Matt Jankowski | bae694108a | |
Claire | 9189e90ff2 | |
Matt Jankowski | 5e060e1f44 | |
Matt Jankowski | 41eb49b984 | |
Claire | a89b02af92 | |
Claire | 1ed0ff30d3 | |
Claire | b233da5996 | |
Eugen Rochko | 8131a5b330 | |
Claire | 6693a4fe7c | |
Claire | 598e63dad2 | |
Claire | 1eb51bd749 | |
Matt Jankowski | 88d33f361f | |
fusagiko / takayamaki | f50105779b | |
fusagiko / takayamaki | 5a5975d7f7 | |
Claire | 32a030dd74 | |
Eugen Rochko | 0ad2413b35 | |
Eugen Rochko | f1c1fa1411 | |
Nick Schonning | fc56eda94b | |
fusagiko / takayamaki | 15fd712464 | |
fusagiko / takayamaki | 81f75b1e0e | |
Matt Jankowski | c53fe9b753 | |
Matt Jankowski | d902a707a3 | |
Matt Jankowski | d00e45a7d3 | |
Matt Jankowski | af824db398 | |
Claire | c18884de32 | |
Nick Schonning | 6b95aaaa65 | |
Josh McKinney | 89c01383f9 | |
Eugen Rochko | 0a08e9d3d3 | |
Mark Roszko | c23d285b16 | |
João Pedro Marques | 8f6e290c7a | |
dependabot[bot] | 0669822ae8 | |
dependabot[bot] | 242d7864f1 | |
dependabot[bot] | 56cf092058 | |
dependabot[bot] | fa14976a5d | |
dependabot[bot] | 819daeb651 | |
dependabot[bot] | 921bef6799 | |
Daniel M Brasil | e8fe941015 | |
Matt Jankowski | 2e43461100 | |
Matt Jankowski | 5a2aa06a51 | |
Matt Jankowski | bdc74086e6 | |
Matt Jankowski | 6e226f5a32 | |
Nick Schonning | 470b8abb69 | |
Matt Jankowski | 60ac9e8634 | |
Matt Jankowski | 8dcfb6e0ea | |
Claire | 678d836c7d | |
Claire | cf1bc4bb93 | |
Nick Schonning | f22b4e556c | |
Christian Schmidt | bfeccf6748 | |
Matt Jankowski | 274d561430 | |
mogaminsk | e0d075713f | |
Matt Jankowski | 4cfe52635c | |
Claire | e79998a11a | |
Eugen Rochko | 38eeed6cbf | |
Nick Schonning | 1033598416 | |
Claire | edec08b970 | |
Claire | cb97a92954 | |
Claire | 103b6de8b2 | |
Eugen Rochko | 7b01b7c3bf | |
Eugen Rochko | 8015297f9e | |
Chike Nwaenie | 374a109546 | |
Christian Schmidt | 0091b28ffe | |
Claire | 11b34a903a | |
Claire | 0a813d96db | |
fusagiko / takayamaki | 66bda4713e | |
Claire | 612a1ee697 | |
Claire | 12b935fadf | |
Claire | 105f8687e4 | |
Claire | 2a3a110f00 | |
Claire | faa336e3f7 | |
Eugen Rochko | 8979b70975 | |
Claire | 1c61869eed | |
Eugen Rochko | 6028d047b9 | |
Eugen Rochko | 2b0f1f365a | |
Eugen Rochko | 7cf963eec2 | |
Claire | a5bc4ea550 | |
Matt Jankowski | ece38b9318 | |
Nick Schonning | 8e514b1965 | |
dependabot[bot] | d9e9579832 | |
Daniel M Brasil | 1d9969fadf | |
Nick Schonning | 49fad26eca | |
Claire | d8a06c1375 | |
Eugen Rochko | d4511f2a76 | |
Plastikmensch | 1565af1caf | |
Nick Schonning | 5841f1af8c | |
Nick Schonning | a3393d0d07 | |
Matt Jankowski | 91a8cd21d8 | |
dependabot[bot] | 3029aeb838 | |
dependabot[bot] | 185a71f281 | |
dependabot[bot] | b839babb39 | |
dependabot[bot] | 785b0349eb | |
dependabot[bot] | 872c4e1ef2 | |
Nick Schonning | 90beba57d8 | |
dependabot[bot] | c7cd891e86 | |
Nick Schonning | 6403d7841e | |
Matias Lago Evia | 93a84f4704 | |
dependabot[bot] | 2f5608e9e5 | |
dependabot[bot] | 5f624954be | |
dependabot[bot] | 9650a5738a | |
Nick Schonning | dcdc614bd2 | |
dependabot[bot] | b31ee9ab38 | |
dependabot[bot] | 1820b55a11 | |
dependabot[bot] | 0c66358601 | |
dependabot[bot] | 855cf7802d | |
dependabot[bot] | fba60094a2 | |
Claire | b0bf6216e6 | |
Claire | 62ab7506d6 | |
Emelia Smith | 301e03eb8c | |
Tim Campbell | 36631e40cc | |
Claire | 1527b02c6d | |
Claire | 1419f90ef2 | |
Plastikmensch | 678480d4d3 | |
Plastikmensch | aea7866161 | |
Claire | 276c39361b | |
Eugen Rochko | 6084461cd0 | |
Eugen Rochko | c35e3cb6ac | |
Eugen Rochko | 8099ba04be | |
Claire | e9a79d46cd | |
Matt Jankowski | 1ac9219b31 | |
Matt Jankowski | 930d84d40e | |
Claire | f45961aa98 | |
Eugen Rochko | 804aa8d501 | |
Nick Schonning | 2daa5a1549 | |
Eugen Rochko | 290e4aba31 | |
dependabot[bot] | 0c81eec239 | |
dependabot[bot] | 03ea084f0d | |
Nick Schonning | 0bfd9f7f73 | |
Christian Schmidt | 5141697323 | |
Nick Schonning | 2904fd0fdd | |
Nick Schonning | 0c7ce98ff6 | |
Nick Schonning | ef3675d688 | |
Matt Jankowski | 0a5f0a8b20 | |
Chike Nwaenie | e1b4eeb636 | |
Christian Schmidt | e713c545b8 | |
Nick Schonning | 4687967176 | |
Claire | 528b8e7e3a | |
Claire | 58a1b2e330 | |
Claire | 5dc3173ef8 | |
Eugen Rochko | 0461f83320 | |
Eugen Rochko | 9d75b03ba4 | |
Claire | 501d6197c4 | |
Claire | fbb4de3dbc | |
Claire | b0eba1a060 | |
dependabot[bot] | 88ce59505e | |
Claire | 37886c28da | |
Daniel M Brasil | faf657d709 | |
Tim Campbell | c62604b5f6 | |
Tim Campbell | e798b8615c | |
fusagiko / takayamaki | c1a7e38d2b | |
Eugen Rochko | e98c86050a |
|
@ -26,7 +26,6 @@ services:
|
||||||
ports:
|
ports:
|
||||||
- '127.0.0.1:3000:3000'
|
- '127.0.0.1:3000:3000'
|
||||||
- '127.0.0.1:4000:4000'
|
- '127.0.0.1:4000:4000'
|
||||||
- '127.0.0.1:80:3000'
|
|
||||||
networks:
|
networks:
|
||||||
- external_network
|
- external_network
|
||||||
- internal_network
|
- internal_network
|
||||||
|
|
34
.eslintrc.js
34
.eslintrc.js
|
@ -7,6 +7,7 @@ module.exports = {
|
||||||
'plugin:jsx-a11y/recommended',
|
'plugin:jsx-a11y/recommended',
|
||||||
'plugin:import/recommended',
|
'plugin:import/recommended',
|
||||||
'plugin:promise/recommended',
|
'plugin:promise/recommended',
|
||||||
|
'plugin:jsdoc/recommended',
|
||||||
],
|
],
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
|
@ -27,6 +28,7 @@ module.exports = {
|
||||||
'import',
|
'import',
|
||||||
'promise',
|
'promise',
|
||||||
'@typescript-eslint',
|
'@typescript-eslint',
|
||||||
|
'formatjs',
|
||||||
],
|
],
|
||||||
|
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
|
@ -71,7 +73,7 @@ module.exports = {
|
||||||
'comma-style': ['warn', 'last'],
|
'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],
|
indent: ['warn', 2],
|
||||||
'jsx-quotes': ['error', 'prefer-single'],
|
'jsx-quotes': ['error', 'prefer-single'],
|
||||||
'no-case-declarations': 'off',
|
'no-case-declarations': 'off',
|
||||||
|
@ -218,6 +220,33 @@ 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: [
|
overrides: [
|
||||||
|
@ -250,10 +279,13 @@ module.exports = {
|
||||||
'plugin:import/recommended',
|
'plugin:import/recommended',
|
||||||
'plugin:import/typescript',
|
'plugin:import/typescript',
|
||||||
'plugin:promise/recommended',
|
'plugin:promise/recommended',
|
||||||
|
'plugin:jsdoc/recommended',
|
||||||
],
|
],
|
||||||
|
|
||||||
rules: {
|
rules: {
|
||||||
'@typescript-eslint/no-explicit-any': 'off',
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
|
||||||
|
'jsdoc/require-jsdoc': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,9 +43,16 @@ jobs:
|
||||||
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 }}
|
||||||
|
|
|
@ -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
|
run: yarn --frozen-lockfile
|
||||||
|
|
||||||
- name: ESLint
|
- name: ESLint
|
||||||
run: yarn test:lint:js
|
run: yarn test:lint:js --max-warnings 0
|
||||||
|
|
||||||
- name: Typecheck
|
- name: Typecheck
|
||||||
run: yarn test:typecheck
|
run: yarn test:typecheck
|
||||||
|
|
|
@ -9,7 +9,6 @@ on:
|
||||||
env:
|
env:
|
||||||
BUNDLE_CLEAN: true
|
BUNDLE_CLEAN: true
|
||||||
BUNDLE_FROZEN: true
|
BUNDLE_FROZEN: true
|
||||||
BUNDLE_WITHOUT: 'development production'
|
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
@ -19,8 +18,17 @@ jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
mode:
|
||||||
|
- production
|
||||||
|
- test
|
||||||
env:
|
env:
|
||||||
RAILS_ENV: test
|
RAILS_ENV: ${{ matrix.mode }}
|
||||||
|
BUNDLE_WITH: ${{ matrix.mode }}
|
||||||
|
OTP_SECRET: precompile_placeholder
|
||||||
|
SECRET_KEY_BASE: precompile_placeholder
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
@ -50,6 +58,7 @@ jobs:
|
||||||
./bin/rails assets:precompile
|
./bin/rails assets:precompile
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: matrix.mode == 'test'
|
||||||
with:
|
with:
|
||||||
path: |-
|
path: |-
|
||||||
./public/assets
|
./public/assets
|
||||||
|
@ -97,14 +106,13 @@ jobs:
|
||||||
PAM_ENABLED: true
|
PAM_ENABLED: true
|
||||||
PAM_DEFAULT_SERVICE: pam_test
|
PAM_DEFAULT_SERVICE: pam_test
|
||||||
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
||||||
BUNDLE_WITH: 'pam_authentication'
|
BUNDLE_WITH: 'pam_authentication test'
|
||||||
CI_JOBS: ${{ matrix.ci_job }}/4
|
CI_JOBS: ${{ matrix.ci_job }}/4
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '2.7'
|
|
||||||
- '3.0'
|
- '3.0'
|
||||||
- '3.1'
|
- '3.1'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
|
@ -136,10 +144,6 @@ jobs:
|
||||||
ruby-version: ${{ matrix.ruby-version}}
|
ruby-version: ${{ matrix.ruby-version}}
|
||||||
bundler-cache: true
|
bundler-cache: true
|
||||||
|
|
||||||
- name: Update system gems
|
|
||||||
if: matrix.ruby-version == '2.7'
|
|
||||||
run: gem update --system
|
|
||||||
|
|
||||||
- name: Load database schema
|
- name: Load database schema
|
||||||
run: './bin/rails db:create db:schema:load db:seed'
|
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
|
- rubocop-capybara
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 2.7 # Set to minimum supported version of CI
|
TargetRubyVersion: 3.0 # Set to minimum supported version of CI
|
||||||
DisplayCopNames: true
|
DisplayCopNames: true
|
||||||
DisplayStyleGuide: true
|
DisplayStyleGuide: true
|
||||||
ExtraDetails: true
|
ExtraDetails: true
|
||||||
|
@ -65,6 +65,7 @@ Metrics/AbcSize:
|
||||||
Metrics/BlockLength:
|
Metrics/BlockLength:
|
||||||
CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
|
CountAsOne: ['array', 'hash', 'heredoc', 'method_call']
|
||||||
Exclude:
|
Exclude:
|
||||||
|
- 'config/routes.rb'
|
||||||
- 'lib/mastodon/*_cli.rb'
|
- 'lib/mastodon/*_cli.rb'
|
||||||
- 'lib/tasks/*.rake'
|
- 'lib/tasks/*.rake'
|
||||||
- 'app/models/concerns/account_associations.rb'
|
- 'app/models/concerns/account_associations.rb'
|
||||||
|
@ -85,6 +86,7 @@ Metrics/BlockLength:
|
||||||
- 'config/initializers/simple_form.rb'
|
- 'config/initializers/simple_form.rb'
|
||||||
- 'config/navigation.rb'
|
- 'config/navigation.rb'
|
||||||
- 'config/routes.rb'
|
- 'config/routes.rb'
|
||||||
|
- 'config/routes/*.rb'
|
||||||
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
|
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
|
||||||
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
|
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
|
||||||
- 'lib/paperclip/gif_transcoder.rb'
|
- 'lib/paperclip/gif_transcoder.rb'
|
||||||
|
@ -130,6 +132,7 @@ Metrics/ClassLength:
|
||||||
- 'app/services/activitypub/process_account_service.rb'
|
- 'app/services/activitypub/process_account_service.rb'
|
||||||
- 'app/services/activitypub/process_status_update_service.rb'
|
- 'app/services/activitypub/process_status_update_service.rb'
|
||||||
- 'app/services/backup_service.rb'
|
- 'app/services/backup_service.rb'
|
||||||
|
- 'app/services/bulk_import_service.rb'
|
||||||
- 'app/services/delete_account_service.rb'
|
- 'app/services/delete_account_service.rb'
|
||||||
- 'app/services/fan_out_on_write_service.rb'
|
- 'app/services/fan_out_on_write_service.rb'
|
||||||
- 'app/services/fetch_link_card_service.rb'
|
- 'app/services/fetch_link_card_service.rb'
|
||||||
|
@ -158,6 +161,11 @@ Metrics/MethodLength:
|
||||||
Metrics/ModuleLength:
|
Metrics/ModuleLength:
|
||||||
CountAsOne: [array, heredoc]
|
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
|
# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus
|
||||||
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
|
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus
|
||||||
Rails/HttpStatus:
|
Rails/HttpStatus:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
1
Aptfile
1
Aptfile
|
@ -1,4 +1,5 @@
|
||||||
ffmpeg
|
ffmpeg
|
||||||
|
libopenblas0-pthread
|
||||||
libpq-dev
|
libpq-dev
|
||||||
libxdamage1
|
libxdamage1
|
||||||
libxfixes3
|
libxfixes3
|
||||||
|
|
12
Dockerfile
12
Dockerfile
|
@ -42,7 +42,7 @@ RUN \
|
||||||
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 --immutable && \
|
yarn install && \
|
||||||
yarn cache clean
|
yarn cache clean
|
||||||
|
|
||||||
# Precompile assets
|
# Precompile assets
|
||||||
|
@ -58,12 +58,16 @@ ENV RAILS_ENV="production" \
|
||||||
ENV OTP_SECRET=precompile_placeholder \
|
ENV OTP_SECRET=precompile_placeholder \
|
||||||
SECRET_KEY_BASE=precompile_placeholder \
|
SECRET_KEY_BASE=precompile_placeholder \
|
||||||
RAKE_NO_YARN_INSTALL_HACK=1
|
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
|
bundle exec rails assets:precompile
|
||||||
|
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
|
@ -108,7 +112,9 @@ 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" \
|
||||||
SOURCE_TAG="${SOURCE_TAG}"
|
SOURCE_TAG="${SOURCE_TAG}" \
|
||||||
|
MASTODON_VERSION_FLAGS="${MASTODON_VERSION_FLAGS}" \
|
||||||
|
MASTODON_VERSION_SUFFIX="${MASTODON_VERSION_SUFFIX}"
|
||||||
|
|
||||||
# Set the run user
|
# Set the run user
|
||||||
USER mastodon
|
USER mastodon
|
||||||
|
|
13
Gemfile
13
Gemfile
|
@ -1,7 +1,7 @@
|
||||||
# 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'
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ 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'
|
||||||
|
@ -30,7 +30,7 @@ gem 'browser'
|
||||||
gem 'charlock_holmes', '~> 0.7.7'
|
gem 'charlock_holmes', '~> 0.7.7'
|
||||||
gem 'chewy', '~> 7.3'
|
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'
|
||||||
|
@ -76,7 +76,7 @@ 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.1'
|
||||||
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'
|
||||||
|
@ -121,7 +121,7 @@ group :test do
|
||||||
gem 'capybara', '~> 3.39'
|
gem 'capybara', '~> 3.39'
|
||||||
gem 'climate_control'
|
gem 'climate_control'
|
||||||
gem 'faker', '~> 3.2'
|
gem 'faker', '~> 3.2'
|
||||||
gem 'json-schema', '~> 3.0'
|
gem 'json-schema', '~> 4.0'
|
||||||
gem 'rack-test', '~> 2.1'
|
gem 'rack-test', '~> 2.1'
|
||||||
gem 'rails-controller-testing', '~> 1.0'
|
gem 'rails-controller-testing', '~> 1.0'
|
||||||
gem 'rspec_junit_formatter', '~> 0.6'
|
gem 'rspec_junit_formatter', '~> 0.6'
|
||||||
|
@ -163,3 +163,4 @@ 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'
|
||||||
|
|
86
Gemfile.lock
86
Gemfile.lock
|
@ -104,12 +104,12 @@ 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.743.0)
|
aws-partitions (1.752.0)
|
||||||
aws-sdk-core (3.171.0)
|
aws-sdk-core (3.171.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)
|
||||||
|
@ -118,7 +118,7 @@ GEM
|
||||||
aws-sdk-kms (1.63.0)
|
aws-sdk-kms (1.63.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.120.1)
|
aws-sdk-s3 (1.121.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)
|
||||||
|
@ -142,7 +142,7 @@ 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 (5.3.1)
|
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)
|
||||||
|
@ -156,7 +156,7 @@ GEM
|
||||||
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)
|
||||||
|
@ -179,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.3.0)
|
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
|
||||||
|
@ -189,26 +189,26 @@ GEM
|
||||||
coderay (1.1.3)
|
coderay (1.1.3)
|
||||||
color_diff (0.1)
|
color_diff (0.1)
|
||||||
concurrent-ruby (1.2.2)
|
concurrent-ruby (1.2.2)
|
||||||
connection_pool (2.3.0)
|
connection_pool (2.4.0)
|
||||||
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.2)
|
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)
|
||||||
|
@ -241,7 +241,7 @@ 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.2.0)
|
faker (3.2.0)
|
||||||
i18n (>= 1.8.11, < 2)
|
i18n (>= 1.8.11, < 2)
|
||||||
|
@ -315,7 +315,7 @@ GEM
|
||||||
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)
|
||||||
|
@ -349,15 +349,15 @@ 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.1)
|
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.4)
|
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, < 4)
|
rack (>= 2.2, < 4)
|
||||||
|
@ -365,7 +365,7 @@ GEM
|
||||||
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)
|
||||||
|
@ -381,8 +381,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)
|
||||||
|
@ -417,11 +417,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.1)
|
||||||
minitest (5.18.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)
|
||||||
|
@ -438,7 +438,7 @@ 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.9)
|
nio4r (2.5.9)
|
||||||
nokogiri (1.14.3)
|
nokogiri (1.14.3)
|
||||||
mini_portile2 (~> 2.8.0)
|
mini_portile2 (~> 2.8.0)
|
||||||
|
@ -481,18 +481,18 @@ GEM
|
||||||
openssl (> 2.0)
|
openssl (> 2.0)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ox (2.14.16)
|
ox (2.14.16)
|
||||||
parallel (1.22.1)
|
parallel (1.23.0)
|
||||||
parser (3.2.2.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.6)
|
pg (1.5.3)
|
||||||
pghero (3.3.2)
|
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)
|
||||||
|
@ -502,13 +502,13 @@ GEM
|
||||||
premailer (~> 1.7, >= 1.7.9)
|
premailer (~> 1.7, >= 1.7.9)
|
||||||
private_address_check (0.5.0)
|
private_address_check (0.5.0)
|
||||||
public_suffix (5.0.1)
|
public_suffix (5.0.1)
|
||||||
puma (6.2.1)
|
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.4)
|
rack (2.2.7)
|
||||||
rack-attack (6.6.1)
|
rack-attack (6.6.1)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rack-cors (2.0.1)
|
rack-cors (2.0.1)
|
||||||
|
@ -568,25 +568,25 @@ GEM
|
||||||
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.1.2)
|
||||||
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.12.1)
|
rspec-core (3.12.2)
|
||||||
rspec-support (~> 3.12.0)
|
rspec-support (~> 3.12.0)
|
||||||
rspec-expectations (3.12.2)
|
rspec-expectations (3.12.3)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.12.0)
|
rspec-support (~> 3.12.0)
|
||||||
rspec-mocks (3.12.3)
|
rspec-mocks (3.12.5)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.12.0)
|
rspec-support (~> 3.12.0)
|
||||||
rspec-rails (6.0.1)
|
rspec-rails (6.0.1)
|
||||||
|
@ -604,7 +604,7 @@ GEM
|
||||||
rspec_chunked (0.6)
|
rspec_chunked (0.6)
|
||||||
rspec_junit_formatter (0.6.0)
|
rspec_junit_formatter (0.6.0)
|
||||||
rspec-core (>= 2, < 4, != 2.12.0)
|
rspec-core (>= 2, < 4, != 2.12.0)
|
||||||
rubocop (1.49.0)
|
rubocop (1.50.2)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.2.0.0)
|
parser (>= 3.2.0.0)
|
||||||
|
@ -616,12 +616,12 @@ GEM
|
||||||
unicode-display_width (>= 2.4.0, < 3.0)
|
unicode-display_width (>= 2.4.0, < 3.0)
|
||||||
rubocop-ast (1.28.0)
|
rubocop-ast (1.28.0)
|
||||||
parser (>= 3.2.1.0)
|
parser (>= 3.2.1.0)
|
||||||
rubocop-capybara (2.17.1)
|
rubocop-capybara (2.18.0)
|
||||||
rubocop (~> 1.41)
|
rubocop (~> 1.41)
|
||||||
rubocop-performance (1.17.1)
|
rubocop-performance (1.17.1)
|
||||||
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.18.0)
|
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)
|
||||||
|
@ -633,6 +633,7 @@ GEM
|
||||||
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)
|
||||||
|
@ -793,7 +794,7 @@ DEPENDENCIES
|
||||||
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)
|
||||||
|
@ -819,7 +820,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)
|
||||||
|
@ -842,7 +843,7 @@ DEPENDENCIES
|
||||||
omniauth_openid_connect (~> 0.6.1)
|
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
|
||||||
|
@ -851,7 +852,7 @@ DEPENDENCIES
|
||||||
public_suffix (~> 5.0)
|
public_suffix (~> 5.0)
|
||||||
puma (~> 6.2)
|
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 (~> 2.0)
|
rack-cors (~> 2.0)
|
||||||
rack-test (~> 2.1)
|
rack-test (~> 2.1)
|
||||||
|
@ -873,7 +874,8 @@ DEPENDENCIES
|
||||||
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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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?
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,16 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController
|
||||||
|
|
||||||
PAGINATION_PARAMS = %i(limit).freeze
|
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
|
def create
|
||||||
authorize :domain_allow, :create?
|
authorize :domain_allow, :create?
|
||||||
|
|
||||||
|
@ -29,16 +39,6 @@ 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 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
|
def destroy
|
||||||
authorize @domain_allow, :destroy?
|
authorize @domain_allow, :destroy?
|
||||||
UnallowDomainService.new.call(@domain_allow)
|
UnallowDomainService.new.call(@domain_allow)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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!
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,10 @@ class Api::V1::Instances::TranslationLanguagesController < Api::BaseController
|
||||||
|
|
||||||
before_action :set_languages
|
before_action :set_languages
|
||||||
|
|
||||||
|
vary_by ''
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in 1.day, public: true
|
cache_even_if_authenticated!
|
||||||
render json: @languages
|
render json: @languages
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: @media_attachment.not_processed? ? 202 : 200
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,6 +21,8 @@ class ApplicationController < ActionController::Base
|
||||||
helper_method :omniauth_only?
|
helper_method :omniauth_only?
|
||||||
helper_method :sso_account_settings
|
helper_method :sso_account_settings
|
||||||
helper_method :whitelist_mode?
|
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 ActionController::ParameterMissing, Paperclip::AdapterRegistry::NoHandlerError, with: :bad_request
|
||||||
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
||||||
|
@ -37,9 +39,11 @@ class ApplicationController < ActionController::Base
|
||||||
service_unavailable
|
service_unavailable
|
||||||
end
|
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 :require_functional!, if: :user_signed_in?
|
||||||
|
|
||||||
|
before_action :set_cache_control_defaults
|
||||||
|
|
||||||
skip_before_action :verify_authenticity_token, only: :raise_not_found
|
skip_before_action :verify_authenticity_token, only: :raise_not_found
|
||||||
|
|
||||||
def raise_not_found
|
def raise_not_found
|
||||||
|
@ -56,14 +60,25 @@ class ApplicationController < ActionController::Base
|
||||||
!authorized_fetch_mode?
|
!authorized_fetch_mode?
|
||||||
end
|
end
|
||||||
|
|
||||||
def store_current_location
|
def store_referrer
|
||||||
store_location_for(:user, request.url) unless [:json, :rss].include?(request.format&.to_sym)
|
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
|
end
|
||||||
|
|
||||||
def require_functional!
|
def require_functional!
|
||||||
redirect_to edit_user_registration_path unless current_user.functional?
|
redirect_to edit_user_registration_path unless current_user.functional?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def skip_csrf_meta_tags?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def after_sign_out_path_for(_resource_or_scope)
|
def after_sign_out_path_for(_resource_or_scope)
|
||||||
if ENV['OMNIAUTH_ONLY'] == 'true' && ENV['OIDC_ENABLED'] == 'true'
|
if ENV['OMNIAUTH_ONLY'] == 'true' && ENV['OIDC_ENABLED'] == 'true'
|
||||||
'/auth/auth/openid_connect/logout'
|
'/auth/auth/openid_connect/logout'
|
||||||
|
@ -127,7 +142,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def sso_account_settings
|
def sso_account_settings
|
||||||
ENV.fetch('SSO_ACCOUNT_SETTINGS')
|
ENV.fetch('SSO_ACCOUNT_SETTINGS', nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_account
|
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?
|
@current_session = SessionActivation.find_by(session_id: cookies.signed['_session_id']) if cookies.signed['_session_id'].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def body_class_string
|
||||||
|
@body_classes || ''
|
||||||
|
end
|
||||||
|
|
||||||
def respond_with_error(code)
|
def respond_with_error(code)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.any do
|
format.any do
|
||||||
|
@ -151,4 +170,8 @@ class ApplicationController < ActionController::Base
|
||||||
format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code }
|
format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_control_defaults
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,16 +25,16 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
super(&:build_invite_request)
|
super(&:build_invite_request)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
super do |resource|
|
super do |resource|
|
||||||
resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
|
resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
not_found
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def update_resource(resource, params)
|
def update_resource(resource, params)
|
||||||
|
@ -157,6 +157,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
def set_cache_headers
|
||||||
response.headers['Cache-Control'] = 'private, no-store'
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,7 +60,7 @@ class AuthorizeInteractionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def uri_param
|
def uri_param
|
||||||
params[:uri] || params.fetch(:acct, '').gsub(/\Aacct:/, '')
|
params[:uri] || params.fetch(:acct, '').delete_prefix('acct:')
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
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
|
||||||
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)
|
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(':')
|
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
|
expires_in = options.delete(:expires_in) || 3.minutes
|
||||||
|
@ -176,10 +198,6 @@ module CacheConcern
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
|
||||||
response.headers['Vary'] = public_fetch_mode? ? 'Accept' : 'Accept, Signature'
|
|
||||||
end
|
|
||||||
|
|
||||||
def cache_collection(raw, klass)
|
def cache_collection(raw, klass)
|
||||||
return raw unless klass.respond_to?(:with_includes)
|
return raw unless klass.respond_to?(:with_includes)
|
||||||
|
|
||||||
|
|
|
@ -180,14 +180,15 @@ module SignatureVerification
|
||||||
|
|
||||||
def build_signed_string
|
def build_signed_string
|
||||||
signed_headers.map do |signed_header|
|
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}"
|
"#{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, '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?
|
raise SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank?
|
||||||
|
|
||||||
"(created): #{signature_params['created']}"
|
"(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, '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?
|
raise SignatureVerificationError, 'Pseudo-header (expires) used but corresponding argument missing' if signature_params['expires'].blank?
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ module SignatureVerification
|
||||||
end
|
end
|
||||||
|
|
||||||
if key_id.start_with?('acct:')
|
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)
|
elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
|
||||||
account = ActivityPub::TagManager.instance.uri_to_actor(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) }
|
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!
|
prepend_before_action :redirect_unauthenticated_to_permalinks!
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :set_app_body_class
|
before_action :set_app_body_class
|
||||||
|
|
||||||
|
vary_by 'Accept, Accept-Language, Cookie'
|
||||||
|
end
|
||||||
|
|
||||||
|
def skip_csrf_meta_tags?
|
||||||
|
current_user.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_app_body_class
|
def set_app_body_class
|
||||||
|
|
|
@ -1,18 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CustomCssController < ApplicationController
|
class CustomCssController < ActionController::Base # rubocop:disable Rails/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
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in 3.minutes, public: true
|
expires_in 3.minutes, public: true
|
||||||
request.session_options[:skip] = true
|
|
||||||
render content_type: 'text/css'
|
render content_type: 'text/css'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,7 @@ class Disputes::BaseController < ApplicationController
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -20,4 +21,8 @@ class Disputes::BaseController < ApplicationController
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'admin'
|
@body_classes = 'admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,15 +2,12 @@
|
||||||
|
|
||||||
class EmojisController < ApplicationController
|
class EmojisController < ApplicationController
|
||||||
before_action :set_emoji
|
before_action :set_emoji
|
||||||
before_action :set_cache_headers
|
|
||||||
|
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
expires_in 3.minutes, public: true
|
||||||
format.json do
|
render_with_cache json: @emoji, content_type: 'application/activity+json', serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter
|
||||||
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Filters::StatusesController < ApplicationController
|
||||||
before_action :set_status_filters
|
before_action :set_status_filters
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
PER_PAGE = 20
|
PER_PAGE = 20
|
||||||
|
|
||||||
|
@ -49,4 +50,8 @@ class Filters::StatusesController < ApplicationController
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'admin'
|
@body_classes = 'admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ class FiltersController < ApplicationController
|
||||||
before_action :set_filter, only: [:edit, :update, :destroy]
|
before_action :set_filter, only: [:edit, :update, :destroy]
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@filters = current_account.custom_filters.includes(:keywords, :statuses).order(:phrase)
|
@filters = current_account.custom_filters.includes(:keywords, :statuses).order(:phrase)
|
||||||
|
@ -17,6 +18,8 @@ class FiltersController < ApplicationController
|
||||||
@filter.keywords.build
|
@filter.keywords.build
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@filter = current_account.custom_filters.build(resource_params)
|
@filter = current_account.custom_filters.build(resource_params)
|
||||||
|
|
||||||
|
@ -27,8 +30,6 @@ class FiltersController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit; end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @filter.update(resource_params)
|
if @filter.update(resource_params)
|
||||||
redirect_to filters_path
|
redirect_to filters_path
|
||||||
|
@ -59,4 +60,8 @@ class FiltersController < ApplicationController
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'admin'
|
@body_classes = 'admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,9 @@ class FollowerAccountsController < ApplicationController
|
||||||
include SignatureVerification
|
include SignatureVerification
|
||||||
include WebAppControllerConcern
|
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 :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_around_action :set_locale, if: -> { request.format == :json }
|
||||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||||
|
@ -14,7 +15,7 @@ class FollowerAccountsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
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?
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
|
|
|
@ -5,8 +5,9 @@ class FollowingAccountsController < ApplicationController
|
||||||
include SignatureVerification
|
include SignatureVerification
|
||||||
include WebAppControllerConcern
|
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 :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_around_action :set_locale, if: -> { request.format == :json }
|
||||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||||
|
@ -14,7 +15,7 @@ class FollowingAccountsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
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?
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
|
|
|
@ -6,7 +6,7 @@ class HomeController < ApplicationController
|
||||||
before_action :set_instance_presenter
|
before_action :set_instance_presenter
|
||||||
|
|
||||||
def index
|
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class InstanceActorsController < ApplicationController
|
class InstanceActorsController < ActivityPub::BaseController
|
||||||
include AccountControllerConcern
|
vary_by ''
|
||||||
|
|
||||||
skip_before_action :check_account_confirmation
|
serialization_scope nil
|
||||||
skip_around_action :set_locale
|
|
||||||
|
before_action :set_account
|
||||||
|
skip_before_action :require_functional!
|
||||||
|
skip_before_action :update_user_sign_in
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in 10.minutes, public: true
|
expires_in 10.minutes, public: true
|
||||||
|
|
|
@ -9,7 +9,7 @@ class IntentsController < ApplicationController
|
||||||
if uri.scheme == 'web+mastodon'
|
if uri.scheme == 'web+mastodon'
|
||||||
case uri.host
|
case uri.host
|
||||||
when 'follow'
|
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'
|
when 'share'
|
||||||
return redirect_to share_path(text: uri.query_values['text'])
|
return redirect_to share_path(text: uri.query_values['text'])
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ class InvitesController < ApplicationController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :invite, :create?
|
authorize :invite, :create?
|
||||||
|
@ -54,4 +55,8 @@ class InvitesController < ApplicationController
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'admin'
|
@body_classes = 'admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ManifestsController < ApplicationController
|
class ManifestsController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||||
skip_before_action :store_current_location
|
# Prevent `active_model_serializer`'s `ActionController::Serialization` from calling `current_user`
|
||||||
skip_before_action :require_functional!
|
# and thus re-issuing session cookies
|
||||||
|
serialization_scope nil
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in 3.minutes, public: true
|
expires_in 3.minutes, public: true
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
class MediaController < ApplicationController
|
class MediaController < ApplicationController
|
||||||
include Authorization
|
include Authorization
|
||||||
|
|
||||||
skip_before_action :store_current_location
|
|
||||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||||
|
|
||||||
before_action :authenticate_user!, if: :whitelist_mode?
|
before_action :authenticate_user!, if: :whitelist_mode?
|
||||||
|
|
|
@ -6,7 +6,6 @@ class MediaProxyController < ApplicationController
|
||||||
include Redisable
|
include Redisable
|
||||||
include Lockable
|
include Lockable
|
||||||
|
|
||||||
skip_before_action :store_current_location
|
|
||||||
skip_before_action :require_functional!
|
skip_before_action :require_functional!
|
||||||
|
|
||||||
before_action :authenticate_user!, if: :whitelist_mode?
|
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
|
rescue_from HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, with: :internal_server_error
|
||||||
|
|
||||||
def show
|
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])
|
@media_attachment = MediaAttachment.remote.attached.find(params[:id])
|
||||||
authorize @media_attachment.status, :show?
|
authorize @media_attachment.status, :show?
|
||||||
redownload! if @media_attachment.needs_redownload? && !reject_media?
|
redownload! if @media_attachment.needs_redownload? && !reject_media?
|
||||||
|
|
|
@ -39,6 +39,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
def set_cache_headers
|
||||||
response.headers['Cache-Control'] = 'private, no-store'
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :require_not_suspended!, only: :destroy
|
before_action :require_not_suspended!, only: :destroy
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
skip_before_action :require_functional!
|
skip_before_action :require_functional!
|
||||||
|
|
||||||
|
@ -35,4 +36,8 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
forbidden if current_account.suspended?
|
forbidden if current_account.suspended?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ class PrivacyController < ApplicationController
|
||||||
before_action :set_instance_presenter
|
before_action :set_instance_presenter
|
||||||
|
|
||||||
def show
|
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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -8,6 +8,7 @@ class RelationshipsController < ApplicationController
|
||||||
before_action :set_pack
|
before_action :set_pack
|
||||||
before_action :set_relationships, only: :show
|
before_action :set_relationships, only: :show
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
|
before_action :set_cache_headers
|
||||||
|
|
||||||
helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
|
helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
|
||||||
|
|
||||||
|
@ -75,4 +76,8 @@ class RelationshipsController < ApplicationController
|
||||||
def set_pack
|
def set_pack
|
||||||
use_pack 'admin'
|
use_pack 'admin'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,6 +8,8 @@ class Settings::ApplicationsController < Settings::BaseController
|
||||||
@applications = current_user.applications.order(id: :desc).page(params[:page])
|
@applications = current_user.applications.order(id: :desc).page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@application = Doorkeeper::Application.new(
|
@application = Doorkeeper::Application.new(
|
||||||
redirect_uri: Doorkeeper.configuration.native_redirect_uri,
|
redirect_uri: Doorkeeper.configuration.native_redirect_uri,
|
||||||
|
@ -15,8 +17,6 @@ class Settings::ApplicationsController < Settings::BaseController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show; end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@application = current_user.applications.build(application_params)
|
@application = current_user.applications.build(application_params)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Settings::BaseController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_cache_headers
|
def set_cache_headers
|
||||||
response.headers['Cache-Control'] = 'private, no-store'
|
response.cache_control.replace(private: true, no_store: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_not_suspended!
|
def require_not_suspended!
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Settings::ExportsController < Settings::BaseController
|
||||||
def create
|
def create
|
||||||
backup = nil
|
backup = nil
|
||||||
|
|
||||||
with_lock("backup:#{current_user.id}") do
|
with_redis_lock("backup:#{current_user.id}") do
|
||||||
authorize :backup, :create?
|
authorize :backup, :create?
|
||||||
backup = current_user.backups.create!
|
backup = current_user.backups.create!
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,31 +1,97 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Settings::ImportsController < Settings::BaseController
|
require 'csv'
|
||||||
before_action :set_account
|
|
||||||
|
|
||||||
def show
|
class Settings::ImportsController < Settings::BaseController
|
||||||
@import = Import.new
|
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
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@import = Import.new(import_params)
|
@import = Form::Import.new(import_params.merge(current_account: current_account))
|
||||||
@import.account = @account
|
|
||||||
|
|
||||||
if @import.save
|
if @import.save
|
||||||
ImportWorker.perform_async(@import.id)
|
redirect_to settings_import_path(@import.bulk_import.id)
|
||||||
redirect_to settings_import_path, notice: I18n.t('imports.success')
|
|
||||||
else
|
else
|
||||||
render :show
|
# We need to set recent imports as we are displaying the index again
|
||||||
|
set_recent_imports
|
||||||
|
render :index
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@bulk_import.destroy!
|
||||||
|
redirect_to settings_imports_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_account
|
def import_params
|
||||||
@account = current_user.account
|
params.require(:form_import).permit(:data, :type, :mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
def import_params
|
def set_bulk_import
|
||||||
params.require(:import).permit(:data, :type, :mode)
|
@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
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Settings::Preferences::AppearanceController < Settings::PreferencesController
|
class Settings::Preferences::AppearanceController < Settings::Preferences::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def after_update_redirect_path
|
def after_update_redirect_path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Settings::PreferencesController < Settings::BaseController
|
class Settings::Preferences::BaseController < Settings::BaseController
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
@ -15,7 +15,7 @@ class Settings::PreferencesController < Settings::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def after_update_redirect_path
|
def after_update_redirect_path
|
||||||
settings_preferences_path
|
raise 'Override in controller'
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_params
|
def user_params
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Settings::Preferences::NotificationsController < Settings::PreferencesController
|
class Settings::Preferences::NotificationsController < Settings::Preferences::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def after_update_redirect_path
|
def after_update_redirect_path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Settings::Preferences::OtherController < Settings::PreferencesController
|
class Settings::Preferences::OtherController < Settings::Preferences::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def after_update_redirect_path
|
def after_update_redirect_path
|
||||||
|
|
|
@ -8,9 +8,8 @@ module Settings
|
||||||
before_action :require_otp_enabled
|
before_action :require_otp_enabled
|
||||||
before_action :require_webauthn_enabled, only: [:index, :destroy]
|
before_action :require_webauthn_enabled, only: [:index, :destroy]
|
||||||
|
|
||||||
def new; end
|
|
||||||
|
|
||||||
def index; end
|
def index; end
|
||||||
|
def new; end
|
||||||
|
|
||||||
def options
|
def options
|
||||||
current_user.update(webauthn_id: WebAuthn.generate_user_id) unless current_user.webauthn_id
|
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