mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-13 07:49:29 +00:00
Compare commits
2 Commits
local-only
...
fix-upload
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aa8d9d149 | ||
|
|
6ba67f92c9 |
@@ -1,36 +1,21 @@
|
||||
version: "2"
|
||||
checks:
|
||||
argument-count:
|
||||
enabled: false
|
||||
complex-logic:
|
||||
enabled: false
|
||||
file-lines:
|
||||
enabled: false
|
||||
method-complexity:
|
||||
enabled: false
|
||||
method-count:
|
||||
enabled: false
|
||||
method-lines:
|
||||
enabled: false
|
||||
nested-control-flow:
|
||||
enabled: false
|
||||
return-statements:
|
||||
enabled: false
|
||||
similar-code:
|
||||
enabled: false
|
||||
identical-code:
|
||||
enabled: false
|
||||
plugins:
|
||||
engines:
|
||||
brakeman:
|
||||
enabled: true
|
||||
bundler-audit:
|
||||
enabled: true
|
||||
duplication:
|
||||
enabled: false
|
||||
eslint:
|
||||
enabled: true
|
||||
rubocop:
|
||||
enabled: true
|
||||
scss-lint:
|
||||
enabled: true
|
||||
exclude_patterns:
|
||||
ratings:
|
||||
paths:
|
||||
- "**.rb"
|
||||
- "**.js"
|
||||
- "**.scss"
|
||||
exclude_paths:
|
||||
- spec/
|
||||
- vendor/asset
|
||||
|
||||
30
.env.nanobox
30
.env.nanobox
@@ -35,17 +35,6 @@ PAPERCLIP_SECRET=$PAPERCLIP_SECRET
|
||||
SECRET_KEY_BASE=$SECRET_KEY_BASE
|
||||
OTP_SECRET=$OTP_SECRET
|
||||
|
||||
# VAPID keys (used for push notifications)
|
||||
# You can generate the keys using the following command (first is the private key, second is the public one)
|
||||
# You should only generate this once per instance. If you later decide to change it, all push subscription will
|
||||
# be invalidated, requiring the users to access the website again to resubscribe.
|
||||
#
|
||||
# Generate with `rake mastodon:webpush:generate_vapid_key` task (`nanobox run bundle exec rake mastodon:webpush:generate_vapid_key`)
|
||||
#
|
||||
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
||||
VAPID_PRIVATE_KEY=$VAPID_PRIVATE_KEY
|
||||
VAPID_PUBLIC_KEY=$VAPID_PUBLIC_KEY
|
||||
|
||||
# Registrations
|
||||
# Single user mode will disable registrations and redirect frontpage to the first profile
|
||||
# SINGLE_USER_MODE=true
|
||||
@@ -73,7 +62,7 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
||||
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||
#SMTP_OPENSSL_VERIFY_MODE=peer
|
||||
#SMTP_ENABLE_STARTTLS_AUTO=true
|
||||
#SMTP_TLS=true
|
||||
|
||||
|
||||
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
|
||||
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
||||
@@ -102,23 +91,6 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
||||
# S3_ENDPOINT=
|
||||
# S3_SIGNATURE_VERSION=
|
||||
|
||||
# Swift (optional)
|
||||
# SWIFT_ENABLED=true
|
||||
# SWIFT_USERNAME=
|
||||
# For Keystone V3, the value for SWIFT_TENANT should be the project name
|
||||
# SWIFT_TENANT=
|
||||
# SWIFT_PASSWORD=
|
||||
# Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid
|
||||
# issues with token rate-limiting during high load.
|
||||
# SWIFT_AUTH_URL=
|
||||
# SWIFT_CONTAINER=
|
||||
# SWIFT_OBJECT_URL=
|
||||
# SWIFT_REGION=
|
||||
# Defaults to 'default'
|
||||
# SWIFT_DOMAIN_NAME=
|
||||
# Defaults to 60 seconds. Set to 0 to disable
|
||||
# SWIFT_CACHE_TTL=
|
||||
|
||||
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||
# S3_CLOUDFRONT_HOST=
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Service dependencies
|
||||
# You may set REDIS_URL instead for more advanced options
|
||||
# You may also set REDIS_NAMESPACE to share Redis between multiple Mastodon servers
|
||||
REDIS_HOST=redis
|
||||
REDIS_PORT=6379
|
||||
# You may set DATABASE_URL instead for more advanced options
|
||||
@@ -27,7 +26,7 @@ LOCAL_HTTPS=true
|
||||
# ALTERNATE_DOMAINS=example1.com,example2.com
|
||||
|
||||
# Application secrets
|
||||
# Generate each with the `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
|
||||
# Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
|
||||
PAPERCLIP_SECRET=
|
||||
SECRET_KEY_BASE=
|
||||
OTP_SECRET=
|
||||
@@ -37,7 +36,7 @@ OTP_SECRET=
|
||||
# You should only generate this once per instance. If you later decide to change it, all push subscription will
|
||||
# be invalidated, requiring the users to access the website again to resubscribe.
|
||||
#
|
||||
# Generate with `RAILS_ENV=production bundle exec rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose)
|
||||
# Generate with `rake mastodon:webpush:generate_vapid_key` task (`docker-compose run --rm web rake mastodon:webpush:generate_vapid_key` if you use docker compose)
|
||||
#
|
||||
# For more information visit https://rossta.net/blog/using-the-web-push-api-with-vapid.html
|
||||
VAPID_PRIVATE_KEY=
|
||||
@@ -99,23 +98,6 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
||||
# S3_ENDPOINT=
|
||||
# S3_SIGNATURE_VERSION=
|
||||
|
||||
# Swift (optional)
|
||||
# SWIFT_ENABLED=true
|
||||
# SWIFT_USERNAME=
|
||||
# For Keystone V3, the value for SWIFT_TENANT should be the project name
|
||||
# SWIFT_TENANT=
|
||||
# SWIFT_PASSWORD=
|
||||
# Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid
|
||||
# issues with token rate-limiting during high load.
|
||||
# SWIFT_AUTH_URL=
|
||||
# SWIFT_CONTAINER=
|
||||
# SWIFT_OBJECT_URL=
|
||||
# SWIFT_REGION=
|
||||
# Defaults to 'default'
|
||||
# SWIFT_DOMAIN_NAME=
|
||||
# Defaults to 60 seconds. Set to 0 to disable
|
||||
# SWIFT_CACHE_TTL=
|
||||
|
||||
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||
# S3_CLOUDFRONT_HOST=
|
||||
|
||||
@@ -134,6 +116,3 @@ STREAMING_CLUSTER_NUM=1
|
||||
# If you use Docker, you may want to assign UID/GID manually.
|
||||
# UID=1000
|
||||
# GID=1000
|
||||
|
||||
# Maximum allowed character count
|
||||
# MAX_TOOT_CHARS=500
|
||||
|
||||
@@ -5,14 +5,12 @@ env:
|
||||
browser: true
|
||||
node: true
|
||||
es6: true
|
||||
jest: true
|
||||
|
||||
parser: babel-eslint
|
||||
|
||||
plugins:
|
||||
- react
|
||||
- jsx-a11y
|
||||
- import
|
||||
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
@@ -23,19 +21,8 @@ parserOptions:
|
||||
modules: true
|
||||
spread: true
|
||||
|
||||
settings:
|
||||
import/extensions:
|
||||
- .js
|
||||
import/ignore:
|
||||
- node_modules
|
||||
- \\.(css|scss|json)$
|
||||
import/resolver:
|
||||
node:
|
||||
moduleDirectory:
|
||||
- node_modules
|
||||
- app/javascript
|
||||
|
||||
rules:
|
||||
|
||||
brace-style: warn
|
||||
comma-dangle:
|
||||
- error
|
||||
@@ -138,17 +125,3 @@ rules:
|
||||
jsx-a11y/role-supports-aria-props: off
|
||||
jsx-a11y/scope: warn
|
||||
jsx-a11y/tabindex-no-positive: warn
|
||||
|
||||
import/extensions:
|
||||
- error
|
||||
- always
|
||||
- js: never
|
||||
import/newline-after-import: error
|
||||
import/no-extraneous-dependencies:
|
||||
- error
|
||||
- devDependencies:
|
||||
- "config/webpack/**"
|
||||
- "app/javascript/mastodon/test_setup.js"
|
||||
- "app/javascript/**/__tests__/**"
|
||||
import/no-unresolved: error
|
||||
import/no-webpack-loader-syntax: error
|
||||
|
||||
32
.github/CODEOWNERS
vendored
32
.github/CODEOWNERS
vendored
@@ -1,32 +0,0 @@
|
||||
# CODEOWNERS for tootsuite/mastodon
|
||||
|
||||
# Translators
|
||||
# To add translator, copy these lines, replace `fr` with appropriate language code and replace `@żelipapą` with user's GitHub nickname preceded by `@` sign or e-mail address.
|
||||
# /app/javascript/mastodon/locales/fr.json @żelipapą
|
||||
# /app/views/user_mailer/*.fr.html.erb @żelipapą
|
||||
# /app/views/user_mailer/*.fr.text.erb @żelipapą
|
||||
# /config/locales/*.fr.yml @żelipapą
|
||||
# /config/locales/fr.yml @żelipapą
|
||||
|
||||
# Polish
|
||||
/app/javascript/mastodon/locales/pl.json @m4sk1n
|
||||
/app/views/user_mailer/*.pl.html.erb @m4sk1n
|
||||
/app/views/user_mailer/*.pl.text.erb @m4sk1n
|
||||
/config/locales/*.pl.yml @m4sk1n
|
||||
/config/locales/pl.yml @m4sk1n
|
||||
|
||||
# French
|
||||
/app/javascript/mastodon/locales/fr.json @aldarone
|
||||
/app/javascript/mastodon/locales/whitelist_fr.json @aldarone
|
||||
/app/views/user_mailer/*.fr.html.erb @aldarone
|
||||
/app/views/user_mailer/*.fr.text.erb @aldarone
|
||||
/config/locales/*.fr.yml @aldarone
|
||||
/config/locales/fr.yml @aldarone
|
||||
|
||||
# Dutch
|
||||
/app/javascript/mastodon/locales/nl.json @jeroenpraat
|
||||
/app/javascript/mastodon/locales/whitelist_nl.json @jeroenpraat
|
||||
/app/views/user_mailer/*.nl.html.erb @jeroenpraat
|
||||
/app/views/user_mailer/*.nl.text.erb @jeroenpraat
|
||||
/config/locales/*.nl.yml @jeroenpraat
|
||||
/config/locales/nl.yml @jeroenpraat
|
||||
0
.gitmodules
vendored
0
.gitmodules
vendored
@@ -1 +1 @@
|
||||
2.4.2
|
||||
2.4.1
|
||||
|
||||
14
.travis.yml
14
.travis.yml
@@ -26,25 +26,25 @@ addons:
|
||||
postgresql: 9.4
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
- trusty-media
|
||||
- sourceline: deb https://dl.yarnpkg.com/debian/ stable main
|
||||
key_url: https://dl.yarnpkg.com/debian/pubkey.gpg
|
||||
packages:
|
||||
- ffmpeg
|
||||
- libicu-dev
|
||||
- g++-6
|
||||
- libprotobuf-dev
|
||||
- protobuf-compiler
|
||||
- yarn
|
||||
- libicu-dev
|
||||
|
||||
rvm:
|
||||
- 2.3.4
|
||||
- 2.4.2
|
||||
- 2.4.1
|
||||
|
||||
services:
|
||||
- redis-server
|
||||
|
||||
install:
|
||||
- nvm install
|
||||
- npm install -g yarn
|
||||
- bundle install --path=vendor/bundle --without development production --retry=3 --jobs=16
|
||||
- yarn install
|
||||
|
||||
@@ -55,5 +55,5 @@ before_script:
|
||||
|
||||
script:
|
||||
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
|
||||
- yarn test
|
||||
- bundle exec i18n-tasks check-normalized && bundle exec i18n-tasks unused
|
||||
- npm test
|
||||
- bundle exec i18n-tasks unused
|
||||
|
||||
46
.yarnclean
46
.yarnclean
@@ -1,46 +0,0 @@
|
||||
# test directories
|
||||
__tests__
|
||||
test
|
||||
tests
|
||||
powered-test
|
||||
|
||||
# asset directories
|
||||
docs
|
||||
doc
|
||||
website
|
||||
images
|
||||
# assets
|
||||
|
||||
# examples
|
||||
example
|
||||
examples
|
||||
|
||||
# code coverage directories
|
||||
coverage
|
||||
.nyc_output
|
||||
|
||||
# build scripts
|
||||
Makefile
|
||||
Gulpfile.js
|
||||
Gruntfile.js
|
||||
|
||||
# configs
|
||||
.tern-project
|
||||
.gitattributes
|
||||
.editorconfig
|
||||
.*ignore
|
||||
.eslintrc
|
||||
.jshintrc
|
||||
.flowconfig
|
||||
.documentup.json
|
||||
.yarn-metadata.json
|
||||
.*.yml
|
||||
*.yml
|
||||
|
||||
# misc
|
||||
*.gz
|
||||
*.md
|
||||
|
||||
# for specific ignore
|
||||
!.svgo.yml
|
||||
|
||||
15
CODEOWNERS
Normal file
15
CODEOWNERS
Normal file
@@ -0,0 +1,15 @@
|
||||
# CODEOWNERS for tootsuite/mastodon
|
||||
|
||||
# Translators
|
||||
# To add translator, copy these lines, replace `fr` with appropriate language code and replace `@żelipapą` with user's GitHub nickname preceded by `@` sign or e-mail address.
|
||||
# /app/javascript/mastodon/locales/fr.json @żelipapą
|
||||
# /app/views/user_mailer/*.fr.html.erb @żelipapą
|
||||
# /app/views/user_mailer/*.fr.text.erb @żelipapą
|
||||
# /config/locales/*.fr.yml @żelipapą
|
||||
# /config/locales/fr.yml @żelipapą
|
||||
|
||||
/app/javascript/mastodon/locales/pl.json @m4sk1n
|
||||
/app/views/user_mailer/*.pl.html.erb @m4sk1n
|
||||
/app/views/user_mailer/*.pl.text.erb @m4sk1n
|
||||
/config/locales/*.pl.yml @m4sk1n
|
||||
/config/locales/pl.yml @m4sk1n
|
||||
@@ -1,46 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at beatrix.bitrot@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
@@ -1,36 +1,3 @@
|
||||
# Contributing to Mastodon Glitch Edition #
|
||||
|
||||
Thank you for your interest in contributing to the `glitch-soc` project!
|
||||
Here are some guidelines, and ways you can help.
|
||||
|
||||
> (This document is a bit of a work-in-progress, so please bear with us.
|
||||
> If you don't see what you're looking for here, please don't hesitate to reach out!)
|
||||
|
||||
## Planning ##
|
||||
|
||||
Right now a lot of the planning for this project takes place in our development Discord, or through GitHub Issues and Projects.
|
||||
We're working on ways to improve the planning structure and better solicit feedback, and if you feel like you can help in this respect, feel free to give us a holler.
|
||||
|
||||
## Documentation ##
|
||||
|
||||
The documentation for this repository is available at [`glitch-soc/docs`](https://github.com/glitch-soc/docs) (online at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/)).
|
||||
Right now, we've mostly focused on the features that make this fork different from upstream in some manner.
|
||||
Adding screenshots, improving descriptions, and so forth are all ways to help contribute to the project even if you don't know any code.
|
||||
|
||||
## Frontend Development ##
|
||||
|
||||
Check out [the documentation here](https://glitch-soc.github.io/docs/contributing/frontend/) for more information.
|
||||
|
||||
## Backend Development ##
|
||||
|
||||
See the guidelines below.
|
||||
|
||||
- - -
|
||||
|
||||
You should also try to follow the guidelines set out in the original `CONTRIBUTING.md` from `tootsuite/mastodon`, reproduced below.
|
||||
|
||||
<blockquote>
|
||||
|
||||
CONTRIBUTING
|
||||
============
|
||||
|
||||
@@ -82,5 +49,3 @@ It is expected that you have a working development environment set up (see back-
|
||||
* If you are introducing new strings, they must be using localization methods
|
||||
|
||||
If the JavaScript or CSS assets won't compile due to a syntax error, it's a good sign that the pull request isn't ready for submission yet.
|
||||
|
||||
</blockquote>
|
||||
|
||||
23
Dockerfile
23
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM ruby:2.4.2-alpine3.6
|
||||
FROM ruby:2.4.1-alpine3.6
|
||||
|
||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||
description="A GNU Social-compatible microblogging server"
|
||||
@@ -7,8 +7,6 @@ ENV UID=991 GID=991 \
|
||||
RAILS_SERVE_STATIC_FILES=true \
|
||||
RAILS_ENV=production NODE_ENV=production
|
||||
|
||||
ARG YARN_VERSION=1.3.2
|
||||
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
|
||||
ARG LIBICONV_VERSION=1.15
|
||||
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
||||
|
||||
@@ -21,7 +19,6 @@ RUN apk -U upgrade \
|
||||
build-base \
|
||||
icu-dev \
|
||||
libidn-dev \
|
||||
libressl \
|
||||
libtool \
|
||||
postgresql-dev \
|
||||
protobuf-dev \
|
||||
@@ -35,21 +32,16 @@ RUN apk -U upgrade \
|
||||
imagemagick \
|
||||
libidn \
|
||||
libpq \
|
||||
nodejs \
|
||||
nodejs-npm \
|
||||
nodejs \
|
||||
protobuf \
|
||||
su-exec \
|
||||
tini \
|
||||
yarn \
|
||||
&& update-ca-certificates \
|
||||
&& mkdir -p /tmp/src /opt \
|
||||
&& wget -O yarn.tar.gz "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
|
||||
&& echo "$YARN_DOWNLOAD_SHA256 *yarn.tar.gz" | sha256sum -c - \
|
||||
&& tar -xzf yarn.tar.gz -C /tmp/src \
|
||||
&& rm yarn.tar.gz \
|
||||
&& mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
|
||||
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
||||
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
||||
&& wget -O libiconv.tar.gz "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
||||
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
||||
&& mkdir -p /tmp/src \
|
||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
||||
&& rm libiconv.tar.gz \
|
||||
&& cd /tmp/src/libiconv-$LIBICONV_VERSION \
|
||||
@@ -60,12 +52,11 @@ RUN apk -U upgrade \
|
||||
&& cd /mastodon \
|
||||
&& rm -rf /tmp/* /var/cache/apk/*
|
||||
|
||||
COPY Gemfile Gemfile.lock package.json yarn.lock .yarnclean /mastodon/
|
||||
COPY Gemfile Gemfile.lock package.json yarn.lock /mastodon/
|
||||
|
||||
RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
|
||||
&& bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \
|
||||
&& yarn --pure-lockfile \
|
||||
&& yarn cache clean
|
||||
&& yarn --ignore-optional --pure-lockfile
|
||||
|
||||
COPY . /mastodon
|
||||
|
||||
|
||||
49
Gemfile
49
Gemfile
@@ -5,8 +5,8 @@ ruby '>= 2.3.0', '< 2.5.0'
|
||||
|
||||
gem 'pkg-config', '~> 1.2'
|
||||
|
||||
gem 'puma', '~> 3.10'
|
||||
gem 'rails', '~> 5.1.4'
|
||||
gem 'puma', '~> 3.8'
|
||||
gem 'rails', '~> 5.1.0'
|
||||
gem 'uglifier', '~> 3.2'
|
||||
|
||||
gem 'hamlit-rails', '~> 0.2'
|
||||
@@ -14,21 +14,16 @@ gem 'pg', '~> 0.20'
|
||||
gem 'pghero', '~> 1.7'
|
||||
gem 'dotenv-rails', '~> 2.2'
|
||||
|
||||
gem 'aws-sdk', '~> 2.10', require: false
|
||||
gem 'fog-core', '~> 1.45'
|
||||
gem 'fog-local', '~> 0.4', require: false
|
||||
gem 'fog-openstack', '~> 0.1', require: false
|
||||
gem 'aws-sdk', '~> 2.9'
|
||||
gem 'paperclip', '~> 5.1'
|
||||
gem 'paperclip-av-transcoder', '~> 0.6'
|
||||
gem 'posix-spawn'
|
||||
|
||||
gem 'active_model_serializers', '~> 0.10'
|
||||
gem 'addressable', '~> 2.5'
|
||||
gem 'bootsnap'
|
||||
gem 'browser'
|
||||
gem 'charlock_holmes', '~> 0.7.5'
|
||||
gem 'iso-639'
|
||||
gem 'cld3', '~> 3.2.0'
|
||||
gem 'cld3', '~> 3.1'
|
||||
gem 'devise', '~> 4.2'
|
||||
gem 'devise-two-factor', '~> 3.0'
|
||||
gem 'doorkeeper', '~> 4.2'
|
||||
@@ -41,15 +36,15 @@ gem 'http', '~> 2.2'
|
||||
gem 'http_accept_language', '~> 2.1'
|
||||
gem 'httplog', '~> 0.99'
|
||||
gem 'idn-ruby', require: 'idn'
|
||||
gem 'kaminari', '~> 1.1'
|
||||
gem 'kaminari', '~> 1.0'
|
||||
gem 'link_header', '~> 0.0'
|
||||
gem 'mime-types', '~> 3.1'
|
||||
gem 'nokogiri', '~> 1.8'
|
||||
gem 'nsa', '~> 0.2'
|
||||
gem 'oj', '~> 3.3'
|
||||
gem 'nokogiri', '~> 1.7'
|
||||
gem 'oj', '~> 3.0'
|
||||
gem 'ostatus2', '~> 2.0'
|
||||
gem 'ox', '~> 2.8'
|
||||
gem 'ox', '~> 2.5'
|
||||
gem 'pundit', '~> 1.1'
|
||||
gem 'rabl', '~> 0.13'
|
||||
gem 'rack-attack', '~> 5.0'
|
||||
gem 'rack-cors', '~> 0.4', require: 'rack/cors'
|
||||
gem 'rack-timeout', '~> 0.4'
|
||||
@@ -67,25 +62,25 @@ gem 'sidekiq-bulk', '~>0.1.1'
|
||||
gem 'simple-navigation', '~> 4.0'
|
||||
gem 'simple_form', '~> 3.4'
|
||||
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
||||
gem 'strong_migrations'
|
||||
gem 'statsd-instrument', '~> 2.1'
|
||||
gem 'twitter-text', '~> 1.14'
|
||||
gem 'tzinfo-data', '~> 1.2017'
|
||||
gem 'webpacker', '~> 3.0'
|
||||
gem 'webpacker', '~> 2.0'
|
||||
gem 'webpush'
|
||||
|
||||
gem 'json-ld-preloaded', '~> 2.2.1'
|
||||
gem 'rdf-normalize', '~> 0.3.1'
|
||||
|
||||
group :development, :test do
|
||||
gem 'fabrication', '~> 2.18'
|
||||
gem 'fabrication', '~> 2.16'
|
||||
gem 'fuubar', '~> 2.2'
|
||||
gem 'i18n-tasks', '~> 0.9', require: false
|
||||
gem 'pry-rails', '~> 0.3'
|
||||
gem 'rspec-rails', '~> 3.7'
|
||||
gem 'rspec-rails', '~> 3.6'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'capybara', '~> 2.15'
|
||||
gem 'capybara', '~> 2.14'
|
||||
gem 'climate_control', '~> 0.2'
|
||||
gem 'faker', '~> 1.7'
|
||||
gem 'microformats', '~> 4.0'
|
||||
@@ -93,29 +88,29 @@ group :test do
|
||||
gem 'rspec-sidekiq', '~> 3.0'
|
||||
gem 'simplecov', '~> 0.14', require: false
|
||||
gem 'webmock', '~> 3.0'
|
||||
gem 'parallel_tests', '~> 2.17'
|
||||
gem 'parallel_tests', '~> 2.14'
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem 'active_record_query_trace', '~> 1.5'
|
||||
gem 'annotate', '~> 2.7'
|
||||
gem 'better_errors', '~> 2.4'
|
||||
gem 'better_errors', '~> 2.1'
|
||||
gem 'binding_of_caller', '~> 0.7'
|
||||
gem 'bullet', '~> 5.5'
|
||||
gem 'letter_opener', '~> 1.4'
|
||||
gem 'letter_opener_web', '~> 1.3'
|
||||
gem 'rubocop', require: false
|
||||
gem 'brakeman', '~> 4.0', require: false
|
||||
gem 'bundler-audit', '~> 0.6', require: false
|
||||
gem 'scss_lint', '~> 0.55', require: false
|
||||
gem 'brakeman', '~> 3.6', require: false
|
||||
gem 'bundler-audit', '~> 0.5', require: false
|
||||
gem 'scss_lint', '~> 0.53', require: false
|
||||
|
||||
gem 'capistrano', '~> 3.10'
|
||||
gem 'capistrano-rails', '~> 1.3'
|
||||
gem 'capistrano', '~> 3.8'
|
||||
gem 'capistrano-rails', '~> 1.2'
|
||||
gem 'capistrano-rbenv', '~> 2.1'
|
||||
gem 'capistrano-yarn', '~> 2.0'
|
||||
end
|
||||
|
||||
group :production do
|
||||
gem 'lograge', '~> 0.7'
|
||||
gem 'lograge', '~> 0.5'
|
||||
gem 'redis-rails', '~> 5.0'
|
||||
end
|
||||
|
||||
413
Gemfile.lock
413
Gemfile.lock
@@ -1,45 +1,45 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (5.1.4)
|
||||
actionpack (= 5.1.4)
|
||||
actioncable (5.1.3)
|
||||
actionpack (= 5.1.3)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (~> 0.6.1)
|
||||
actionmailer (5.1.4)
|
||||
actionpack (= 5.1.4)
|
||||
actionview (= 5.1.4)
|
||||
activejob (= 5.1.4)
|
||||
actionmailer (5.1.3)
|
||||
actionpack (= 5.1.3)
|
||||
actionview (= 5.1.3)
|
||||
activejob (= 5.1.3)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.1.4)
|
||||
actionview (= 5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
actionpack (5.1.3)
|
||||
actionview (= 5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
rack (~> 2.0)
|
||||
rack-test (>= 0.6.3)
|
||||
rack-test (~> 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
actionview (5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_model_serializers (0.10.7)
|
||||
active_model_serializers (0.10.6)
|
||||
actionpack (>= 4.1, < 6)
|
||||
activemodel (>= 4.1, < 6)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
|
||||
active_record_query_trace (1.5.4)
|
||||
activejob (5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
activejob (5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
activerecord (5.1.4)
|
||||
activemodel (= 5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
activemodel (5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
activerecord (5.1.3)
|
||||
activemodel (= 5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
arel (~> 8.0)
|
||||
activesupport (5.1.4)
|
||||
activesupport (5.1.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
@@ -57,51 +57,51 @@ GEM
|
||||
encryptor (~> 3.0.0)
|
||||
av (0.9.0)
|
||||
cocaine (~> 0.5.3)
|
||||
aws-sdk (2.10.100)
|
||||
aws-sdk-resources (= 2.10.100)
|
||||
aws-sdk-core (2.10.100)
|
||||
aws-sdk (2.10.21)
|
||||
aws-sdk-resources (= 2.10.21)
|
||||
aws-sdk-core (2.10.21)
|
||||
aws-sigv4 (~> 1.0)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-resources (2.10.100)
|
||||
aws-sdk-core (= 2.10.100)
|
||||
aws-sigv4 (1.0.2)
|
||||
aws-sdk-resources (2.10.21)
|
||||
aws-sdk-core (= 2.10.21)
|
||||
aws-sigv4 (1.0.1)
|
||||
bcrypt (3.1.11)
|
||||
better_errors (2.4.0)
|
||||
better_errors (2.1.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubi (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
rack (>= 0.9.0)
|
||||
binding_of_caller (0.7.3)
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
bootsnap (1.1.5)
|
||||
bootsnap (1.1.2)
|
||||
msgpack (~> 1.0)
|
||||
brakeman (4.0.1)
|
||||
browser (2.5.2)
|
||||
brakeman (3.7.2)
|
||||
browser (2.4.0)
|
||||
builder (3.2.3)
|
||||
bullet (5.6.1)
|
||||
bullet (5.5.1)
|
||||
activesupport (>= 3.0.0)
|
||||
uniform_notifier (~> 1.10.0)
|
||||
bundler-audit (0.6.0)
|
||||
bundler (~> 1.2)
|
||||
thor (~> 0.18)
|
||||
capistrano (3.10.0)
|
||||
capistrano (3.8.2)
|
||||
airbrussh (>= 1.0.0)
|
||||
i18n
|
||||
rake (>= 10.0.0)
|
||||
sshkit (>= 1.9.0)
|
||||
capistrano-bundler (1.3.0)
|
||||
capistrano-bundler (1.2.0)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.2)
|
||||
capistrano-rails (1.3.1)
|
||||
capistrano-rails (1.3.0)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (~> 1.1)
|
||||
capistrano-rbenv (2.1.3)
|
||||
capistrano-rbenv (2.1.1)
|
||||
capistrano (~> 3.1)
|
||||
sshkit (~> 1.3)
|
||||
capistrano-yarn (2.0.2)
|
||||
capistrano (~> 3.0)
|
||||
capybara (2.16.1)
|
||||
capybara (2.14.4)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
@@ -110,18 +110,18 @@ GEM
|
||||
activesupport
|
||||
charlock_holmes (0.7.5)
|
||||
chunky_png (1.3.8)
|
||||
cld3 (3.2.1)
|
||||
cld3 (3.1.3)
|
||||
ffi (>= 1.1.0, < 1.10.0)
|
||||
climate_control (0.2.0)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.1.2)
|
||||
coderay (1.1.1)
|
||||
colorize (0.8.1)
|
||||
concurrent-ruby (1.0.5)
|
||||
connection_pool (2.2.1)
|
||||
crack (0.4.3)
|
||||
safe_yaml (~> 1.0.0)
|
||||
crass (1.0.3)
|
||||
crass (1.0.2)
|
||||
debug_inspector (0.0.3)
|
||||
devise (4.3.0)
|
||||
bcrypt (~> 3.0)
|
||||
@@ -129,11 +129,11 @@ GEM
|
||||
railties (>= 4.1.0, < 5.2)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (3.0.2)
|
||||
activesupport (< 5.2)
|
||||
devise-two-factor (3.0.0)
|
||||
activesupport
|
||||
attr_encrypted (>= 1.3, < 4, != 2)
|
||||
devise (~> 4.0)
|
||||
railties (< 5.2)
|
||||
railties
|
||||
rotp (~> 2.0)
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
@@ -150,41 +150,27 @@ GEM
|
||||
thread
|
||||
thread_safe
|
||||
encryptor (3.0.0)
|
||||
erubi (1.7.0)
|
||||
et-orbi (1.0.8)
|
||||
erubi (1.6.1)
|
||||
erubis (2.7.0)
|
||||
et-orbi (1.0.5)
|
||||
tzinfo
|
||||
excon (0.59.0)
|
||||
execjs (2.7.0)
|
||||
fabrication (2.18.0)
|
||||
faker (1.8.4)
|
||||
fabrication (2.16.2)
|
||||
faker (1.7.3)
|
||||
i18n (~> 0.5)
|
||||
fast_blank (1.0.0)
|
||||
ffi (1.9.18)
|
||||
fog-core (1.45.0)
|
||||
builder
|
||||
excon (~> 0.58)
|
||||
formatador (~> 0.2)
|
||||
fog-json (1.0.2)
|
||||
fog-core (~> 1.0)
|
||||
multi_json (~> 1.10)
|
||||
fog-local (0.4.0)
|
||||
fog-core (~> 1.27)
|
||||
fog-openstack (0.1.22)
|
||||
fog-core (>= 1.40)
|
||||
fog-json (>= 1.0)
|
||||
ipaddress (>= 0.8)
|
||||
formatador (0.2.5)
|
||||
fuubar (2.2.0)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
globalid (0.4.1)
|
||||
globalid (0.4.0)
|
||||
activesupport (>= 4.2.0)
|
||||
goldfinger (2.0.1)
|
||||
addressable (~> 2.5)
|
||||
http (~> 2.2)
|
||||
nokogiri (~> 1.8)
|
||||
oj (~> 3.0)
|
||||
hamlit (2.8.5)
|
||||
hamlit (2.8.4)
|
||||
temple (>= 0.8.0)
|
||||
thor
|
||||
tilt
|
||||
@@ -195,8 +181,8 @@ GEM
|
||||
railties (>= 4.0.1)
|
||||
hamster (3.0.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
hashdiff (0.3.7)
|
||||
highline (1.7.10)
|
||||
hashdiff (0.3.5)
|
||||
highline (1.7.8)
|
||||
hiredis (0.6.1)
|
||||
hkdf (0.3.0)
|
||||
htmlentities (4.3.4)
|
||||
@@ -213,44 +199,41 @@ GEM
|
||||
httplog (0.99.7)
|
||||
colorize
|
||||
rack
|
||||
i18n (0.9.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-tasks (0.9.19)
|
||||
i18n (0.8.6)
|
||||
i18n-tasks (0.9.16)
|
||||
activesupport (>= 4.0.2)
|
||||
ast (>= 2.1.0)
|
||||
easy_translate (>= 0.5.0)
|
||||
erubi
|
||||
erubis
|
||||
highline (>= 1.7.3)
|
||||
i18n
|
||||
parser (>= 2.2.3.0)
|
||||
rainbow (~> 2.2)
|
||||
terminal-table (>= 1.5.1)
|
||||
idn-ruby (0.1.0)
|
||||
ipaddress (0.8.3)
|
||||
iso-639 (0.2.8)
|
||||
jmespath (1.3.1)
|
||||
json (2.1.0)
|
||||
json-ld (2.1.7)
|
||||
json-ld (2.1.5)
|
||||
multi_json (~> 1.12)
|
||||
rdf (~> 2.2, >= 2.2.8)
|
||||
json-ld-preloaded (2.2.2)
|
||||
rdf (~> 2.2)
|
||||
json-ld-preloaded (2.2.1)
|
||||
json-ld (~> 2.1, >= 2.1.5)
|
||||
multi_json (~> 1.11)
|
||||
rdf (~> 2.2)
|
||||
jsonapi-renderer (0.2.0)
|
||||
jwt (2.1.0)
|
||||
kaminari (1.1.1)
|
||||
jsonapi-renderer (0.1.3)
|
||||
jwt (1.5.6)
|
||||
kaminari (1.0.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.1.1)
|
||||
kaminari-activerecord (= 1.1.1)
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-actionview (1.1.1)
|
||||
kaminari-actionview (= 1.0.1)
|
||||
kaminari-activerecord (= 1.0.1)
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-actionview (1.0.1)
|
||||
actionview
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-activerecord (1.1.1)
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-activerecord (1.0.1)
|
||||
activerecord
|
||||
kaminari-core (= 1.1.1)
|
||||
kaminari-core (1.1.1)
|
||||
kaminari-core (= 1.0.1)
|
||||
kaminari-core (1.0.1)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
letter_opener (1.4.1)
|
||||
@@ -260,19 +243,17 @@ GEM
|
||||
letter_opener (~> 1.0)
|
||||
railties (>= 3.2)
|
||||
link_header (0.0.8)
|
||||
lograge (0.7.1)
|
||||
lograge (0.5.1)
|
||||
actionpack (>= 4, < 5.2)
|
||||
activesupport (>= 4, < 5.2)
|
||||
railties (>= 4, < 5.2)
|
||||
request_store (~> 1.0)
|
||||
loofah (2.1.1)
|
||||
crass (~> 1.0.2)
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.0)
|
||||
mini_mime (>= 0.1.1)
|
||||
mail (2.6.6)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mario-redis-lock (1.2.0)
|
||||
redis (~> 3, >= 3.0.5)
|
||||
method_source (0.9.0)
|
||||
method_source (0.8.2)
|
||||
microformats (4.0.7)
|
||||
json
|
||||
nokogiri
|
||||
@@ -280,33 +261,27 @@ GEM
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.2)
|
||||
mini_mime (1.0.0)
|
||||
mini_portile2 (2.3.0)
|
||||
mini_portile2 (2.2.0)
|
||||
minitest (5.10.3)
|
||||
msgpack (1.1.0)
|
||||
multi_json (1.12.2)
|
||||
multi_json (1.12.1)
|
||||
net-scp (1.2.1)
|
||||
net-ssh (>= 2.6.5)
|
||||
net-ssh (4.2.0)
|
||||
net-ssh (4.1.0)
|
||||
nio4r (2.1.0)
|
||||
nokogiri (1.8.1)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
nokogiri (1.8.0)
|
||||
mini_portile2 (~> 2.2.0)
|
||||
nokogumbo (1.4.13)
|
||||
nokogiri
|
||||
nsa (0.2.4)
|
||||
activesupport (>= 4.2, < 6)
|
||||
concurrent-ruby (~> 1.0.0)
|
||||
sidekiq (>= 3.5.0)
|
||||
statsd-ruby (~> 1.2.0)
|
||||
oj (3.3.9)
|
||||
openssl (2.0.6)
|
||||
oj (3.3.4)
|
||||
openssl (2.0.4)
|
||||
orm_adapter (0.5.0)
|
||||
ostatus2 (2.0.1)
|
||||
addressable (~> 2.4)
|
||||
http (~> 2.0)
|
||||
nokogiri (~> 1.6)
|
||||
openssl (~> 2.0)
|
||||
ox (2.8.2)
|
||||
ox (2.5.0)
|
||||
paperclip (5.1.0)
|
||||
activemodel (>= 4.2.0)
|
||||
activesupport (>= 4.2.0)
|
||||
@@ -316,48 +291,48 @@ GEM
|
||||
paperclip-av-transcoder (0.6.4)
|
||||
av (~> 0.9.0)
|
||||
paperclip (>= 2.5.2)
|
||||
parallel (1.12.0)
|
||||
parallel_tests (2.19.0)
|
||||
parallel (1.11.2)
|
||||
parallel_tests (2.14.2)
|
||||
parallel
|
||||
parser (2.4.0.2)
|
||||
ast (~> 2.3)
|
||||
parser (2.4.0.0)
|
||||
ast (~> 2.2)
|
||||
pg (0.21.0)
|
||||
pghero (1.7.0)
|
||||
activerecord
|
||||
pkg-config (1.2.8)
|
||||
posix-spawn (0.3.13)
|
||||
pkg-config (1.2.4)
|
||||
powerpack (0.1.1)
|
||||
pry (0.11.3)
|
||||
pry (0.10.4)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
pry-rails (0.3.6)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (3.0.1)
|
||||
puma (3.11.0)
|
||||
public_suffix (3.0.0)
|
||||
puma (3.9.1)
|
||||
pundit (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
rabl (0.13.1)
|
||||
activesupport (>= 2.3.14)
|
||||
rack (2.0.3)
|
||||
rack-attack (5.0.1)
|
||||
rack
|
||||
rack-cors (0.4.1)
|
||||
rack-protection (2.0.0)
|
||||
rack
|
||||
rack-proxy (0.6.2)
|
||||
rack
|
||||
rack-test (0.8.2)
|
||||
rack (>= 1.0, < 3)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rack-timeout (0.4.2)
|
||||
rails (5.1.4)
|
||||
actioncable (= 5.1.4)
|
||||
actionmailer (= 5.1.4)
|
||||
actionpack (= 5.1.4)
|
||||
actionview (= 5.1.4)
|
||||
activejob (= 5.1.4)
|
||||
activemodel (= 5.1.4)
|
||||
activerecord (= 5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
rails (5.1.3)
|
||||
actioncable (= 5.1.3)
|
||||
actionmailer (= 5.1.3)
|
||||
actionpack (= 5.1.3)
|
||||
actionview (= 5.1.3)
|
||||
activejob (= 5.1.3)
|
||||
activemodel (= 5.1.3)
|
||||
activerecord (= 5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.1.4)
|
||||
railties (= 5.1.3)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-controller-testing (1.0.2)
|
||||
actionpack (~> 5.x, >= 5.0.1)
|
||||
@@ -373,78 +348,74 @@ GEM
|
||||
railties (~> 5.0)
|
||||
rails-settings-cached (0.6.6)
|
||||
rails (>= 4.2.0)
|
||||
railties (5.1.4)
|
||||
actionpack (= 5.1.4)
|
||||
activesupport (= 5.1.4)
|
||||
railties (5.1.3)
|
||||
actionpack (= 5.1.3)
|
||||
activesupport (= 5.1.3)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
rake (12.3.0)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
rdf (2.2.12)
|
||||
rake (12.0.0)
|
||||
rdf (2.2.8)
|
||||
hamster (~> 3.0)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdf-normalize (0.3.2)
|
||||
rdf (~> 2.0)
|
||||
redis (3.3.5)
|
||||
redis-actionpack (5.0.2)
|
||||
redis (3.3.3)
|
||||
redis-actionpack (5.0.1)
|
||||
actionpack (>= 4.0, < 6)
|
||||
redis-rack (>= 1, < 3)
|
||||
redis-store (>= 1.1.0, < 2)
|
||||
redis-activesupport (5.0.4)
|
||||
redis-store (>= 1.1.0, < 1.4.0)
|
||||
redis-activesupport (5.0.3)
|
||||
activesupport (>= 3, < 6)
|
||||
redis-store (>= 1.3, < 2)
|
||||
redis-namespace (1.6.0)
|
||||
redis (>= 3.0.4)
|
||||
redis-rack (2.0.3)
|
||||
redis-store (~> 1.3.0)
|
||||
redis-namespace (1.5.3)
|
||||
redis (~> 3.0, >= 3.0.4)
|
||||
redis-rack (2.0.2)
|
||||
rack (>= 1.5, < 3)
|
||||
redis-store (>= 1.2, < 2)
|
||||
redis-store (>= 1.2, < 1.4)
|
||||
redis-rails (5.0.2)
|
||||
redis-actionpack (>= 5.0, < 6)
|
||||
redis-activesupport (>= 5.0, < 6)
|
||||
redis-store (>= 1.2, < 2)
|
||||
redis-store (1.4.1)
|
||||
redis (>= 2.2, < 5)
|
||||
request_store (1.3.2)
|
||||
redis-store (1.3.0)
|
||||
redis (>= 2.2)
|
||||
responders (2.4.0)
|
||||
actionpack (>= 4.2.0, < 5.3)
|
||||
railties (>= 4.2.0, < 5.3)
|
||||
rotp (2.1.2)
|
||||
rqrcode (0.10.1)
|
||||
chunky_png (~> 1.0)
|
||||
rspec-core (3.7.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-expectations (3.7.0)
|
||||
rspec-core (3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-expectations (3.6.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-mocks (3.7.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-mocks (3.6.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-rails (3.7.2)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-rails (3.6.0)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.7.0)
|
||||
rspec-expectations (~> 3.7.0)
|
||||
rspec-mocks (~> 3.7.0)
|
||||
rspec-support (~> 3.7.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-sidekiq (3.0.3)
|
||||
rspec-core (~> 3.0, >= 3.0.0)
|
||||
sidekiq (>= 2.4.0)
|
||||
rspec-support (3.7.0)
|
||||
rubocop (0.51.0)
|
||||
rspec-support (3.6.0)
|
||||
rubocop (0.49.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 2.2.2, < 3.0)
|
||||
rainbow (>= 1.99.1, < 3.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-oembed (0.12.0)
|
||||
ruby-progressbar (1.9.0)
|
||||
ruby-progressbar (1.8.1)
|
||||
rufus-scheduler (3.4.2)
|
||||
et-orbi (~> 1.0)
|
||||
safe_yaml (1.0.4)
|
||||
@@ -452,28 +423,24 @@ GEM
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.4.4)
|
||||
nokogumbo (~> 1.4.1)
|
||||
sass (3.5.3)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
scss_lint (0.56.0)
|
||||
sass (3.4.24)
|
||||
scss_lint (0.54.0)
|
||||
rake (>= 0.9, < 13)
|
||||
sass (~> 3.5.3)
|
||||
sidekiq (5.0.5)
|
||||
sass (~> 3.4.20)
|
||||
sidekiq (5.0.4)
|
||||
concurrent-ruby (~> 1.0)
|
||||
connection_pool (~> 2.2, >= 2.2.0)
|
||||
rack-protection (>= 1.5.0)
|
||||
redis (>= 3.3.4, < 5)
|
||||
redis (~> 3.3, >= 3.3.3)
|
||||
sidekiq-bulk (0.1.1)
|
||||
activesupport
|
||||
sidekiq
|
||||
sidekiq-scheduler (2.1.10)
|
||||
redis (>= 3, < 5)
|
||||
sidekiq-scheduler (2.1.8)
|
||||
redis (~> 3)
|
||||
rufus-scheduler (~> 3.2)
|
||||
sidekiq (>= 3)
|
||||
tilt (>= 1.4.0)
|
||||
sidekiq-unique-jobs (5.0.10)
|
||||
sidekiq-unique-jobs (5.0.9)
|
||||
sidekiq (>= 4.0, <= 6.0)
|
||||
thor (~> 0)
|
||||
simple-navigation (4.0.5)
|
||||
@@ -481,24 +448,23 @@ GEM
|
||||
simple_form (3.5.0)
|
||||
actionpack (> 4, < 5.2)
|
||||
activemodel (> 4, < 5.2)
|
||||
simplecov (0.15.1)
|
||||
simplecov (0.14.1)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
simplecov-html (0.10.1)
|
||||
slop (3.6.0)
|
||||
sprockets (3.7.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
sprockets-rails (3.2.0)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sshkit (1.15.1)
|
||||
sshkit (1.13.1)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
statsd-ruby (1.2.1)
|
||||
strong_migrations (0.1.9)
|
||||
activerecord (>= 3.2.0)
|
||||
statsd-instrument (2.1.4)
|
||||
temple (0.8.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
@@ -508,9 +474,9 @@ GEM
|
||||
tilt (2.0.8)
|
||||
twitter-text (1.14.7)
|
||||
unf (~> 0.1.0)
|
||||
tzinfo (1.2.4)
|
||||
tzinfo (1.2.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2017.3)
|
||||
tzinfo-data (1.2017.2)
|
||||
tzinfo (>= 1.0.0)
|
||||
uglifier (3.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
@@ -521,20 +487,20 @@ GEM
|
||||
uniform_notifier (1.10.0)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
webmock (3.1.1)
|
||||
webmock (3.0.1)
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff
|
||||
webpacker (3.0.2)
|
||||
webpacker (2.0)
|
||||
activesupport (>= 4.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
multi_json (~> 1.2)
|
||||
railties (>= 4.2)
|
||||
webpush (0.3.3)
|
||||
webpush (0.3.2)
|
||||
hkdf (~> 0.2)
|
||||
jwt (~> 2.0)
|
||||
jwt
|
||||
websocket-driver (0.6.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.3)
|
||||
websocket-extensions (0.1.2)
|
||||
xpath (2.1.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
@@ -546,32 +512,29 @@ DEPENDENCIES
|
||||
active_record_query_trace (~> 1.5)
|
||||
addressable (~> 2.5)
|
||||
annotate (~> 2.7)
|
||||
aws-sdk (~> 2.10)
|
||||
better_errors (~> 2.4)
|
||||
aws-sdk (~> 2.9)
|
||||
better_errors (~> 2.1)
|
||||
binding_of_caller (~> 0.7)
|
||||
bootsnap
|
||||
brakeman (~> 4.0)
|
||||
brakeman (~> 3.6)
|
||||
browser
|
||||
bullet (~> 5.5)
|
||||
bundler-audit (~> 0.6)
|
||||
capistrano (~> 3.10)
|
||||
capistrano-rails (~> 1.3)
|
||||
bundler-audit (~> 0.5)
|
||||
capistrano (~> 3.8)
|
||||
capistrano-rails (~> 1.2)
|
||||
capistrano-rbenv (~> 2.1)
|
||||
capistrano-yarn (~> 2.0)
|
||||
capybara (~> 2.15)
|
||||
capybara (~> 2.14)
|
||||
charlock_holmes (~> 0.7.5)
|
||||
cld3 (~> 3.2.0)
|
||||
cld3 (~> 3.1)
|
||||
climate_control (~> 0.2)
|
||||
devise (~> 4.2)
|
||||
devise-two-factor (~> 3.0)
|
||||
doorkeeper (~> 4.2)
|
||||
dotenv-rails (~> 2.2)
|
||||
fabrication (~> 2.18)
|
||||
fabrication (~> 2.16)
|
||||
faker (~> 1.7)
|
||||
fast_blank (~> 1.0)
|
||||
fog-core (~> 1.45)
|
||||
fog-local (~> 0.4)
|
||||
fog-openstack (~> 0.1)
|
||||
fuubar (~> 2.2)
|
||||
goldfinger (~> 2.0)
|
||||
hamlit-rails (~> 0.2)
|
||||
@@ -582,35 +545,33 @@ DEPENDENCIES
|
||||
httplog (~> 0.99)
|
||||
i18n-tasks (~> 0.9)
|
||||
idn-ruby
|
||||
iso-639
|
||||
json-ld-preloaded (~> 2.2.1)
|
||||
kaminari (~> 1.1)
|
||||
kaminari (~> 1.0)
|
||||
letter_opener (~> 1.4)
|
||||
letter_opener_web (~> 1.3)
|
||||
link_header (~> 0.0)
|
||||
lograge (~> 0.7)
|
||||
lograge (~> 0.5)
|
||||
mario-redis-lock (~> 1.2)
|
||||
microformats (~> 4.0)
|
||||
mime-types (~> 3.1)
|
||||
nokogiri (~> 1.8)
|
||||
nsa (~> 0.2)
|
||||
oj (~> 3.3)
|
||||
nokogiri (~> 1.7)
|
||||
oj (~> 3.0)
|
||||
ostatus2 (~> 2.0)
|
||||
ox (~> 2.8)
|
||||
ox (~> 2.5)
|
||||
paperclip (~> 5.1)
|
||||
paperclip-av-transcoder (~> 0.6)
|
||||
parallel_tests (~> 2.17)
|
||||
parallel_tests (~> 2.14)
|
||||
pg (~> 0.20)
|
||||
pghero (~> 1.7)
|
||||
pkg-config (~> 1.2)
|
||||
posix-spawn
|
||||
pry-rails (~> 0.3)
|
||||
puma (~> 3.10)
|
||||
puma (~> 3.8)
|
||||
pundit (~> 1.1)
|
||||
rabl (~> 0.13)
|
||||
rack-attack (~> 5.0)
|
||||
rack-cors (~> 0.4)
|
||||
rack-timeout (~> 0.4)
|
||||
rails (~> 5.1.4)
|
||||
rails (~> 5.1.0)
|
||||
rails-controller-testing (~> 1.0)
|
||||
rails-i18n (~> 5.0)
|
||||
rails-settings-cached (~> 0.6)
|
||||
@@ -619,12 +580,12 @@ DEPENDENCIES
|
||||
redis-namespace (~> 1.5)
|
||||
redis-rails (~> 5.0)
|
||||
rqrcode (~> 0.10)
|
||||
rspec-rails (~> 3.7)
|
||||
rspec-rails (~> 3.6)
|
||||
rspec-sidekiq (~> 3.0)
|
||||
rubocop
|
||||
ruby-oembed (~> 0.12)
|
||||
sanitize (~> 4.4)
|
||||
scss_lint (~> 0.55)
|
||||
scss_lint (~> 0.53)
|
||||
sidekiq (~> 5.0)
|
||||
sidekiq-bulk (~> 0.1.1)
|
||||
sidekiq-scheduler (~> 2.1)
|
||||
@@ -633,16 +594,16 @@ DEPENDENCIES
|
||||
simple_form (~> 3.4)
|
||||
simplecov (~> 0.14)
|
||||
sprockets-rails (~> 3.2)
|
||||
strong_migrations
|
||||
statsd-instrument (~> 2.1)
|
||||
twitter-text (~> 1.14)
|
||||
tzinfo-data (~> 1.2017)
|
||||
uglifier (~> 3.2)
|
||||
webmock (~> 3.0)
|
||||
webpacker (~> 3.0)
|
||||
webpacker (~> 2.0)
|
||||
webpush
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.4.2p198
|
||||
ruby 2.4.1p111
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.0
|
||||
1.15.4
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
web: PORT=3000 bundle exec puma -C config/puma.rb
|
||||
sidekiq: PORT=3000 bundle exec sidekiq
|
||||
stream: PORT=4000 yarn run start
|
||||
webpack: ./bin/webpack-dev-server --listen-host 0.0.0.0
|
||||
webpack: ./bin/webpack-dev-server --host 0.0.0.0
|
||||
|
||||
72
README.md
72
README.md
@@ -1,10 +1,70 @@
|
||||
# Mastodon Glitch Edition #
|
||||

|
||||
========
|
||||
|
||||
> Now with automated deploys!
|
||||
[][travis]
|
||||
[][code_climate]
|
||||
|
||||
[](https://travis-ci.org/glitch-soc/mastodon)
|
||||
[travis]: https://travis-ci.org/tootsuite/mastodon
|
||||
[code_climate]: https://codeclimate.com/github/tootsuite/mastodon
|
||||
|
||||
So here's the deal: we all work on this code, and then it runs on dev.glitch.social and anyone who uses that does so absolutely at their own risk. can you dig it?
|
||||
Mastodon is a free, open-source social network server. A decentralized solution to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the social network seamlessly.
|
||||
|
||||
- You can view documentation for this project at [glitch-soc.github.io/docs/](https://glitch-soc.github.io/docs/).
|
||||
- And contributing guidelines are available [here](CONTRIBUTING.md) and [here](https://glitch-soc.github.io/docs/contributing/).
|
||||
An alternative implementation of the GNU social project. Based on [ActivityStreams](https://en.wikipedia.org/wiki/Activity_Streams_(format)), [Webfinger](https://en.wikipedia.org/wiki/WebFinger), [WebSub](https://en.wikipedia.org/wiki/WebSub) and [Salmon](https://en.wikipedia.org/wiki/Salmon_(protocol)).
|
||||
|
||||
Click on the screenshot to watch a demo of the UI:
|
||||
|
||||
[][youtube_demo]
|
||||
|
||||
[youtube_demo]: https://www.youtube.com/watch?v=YO1jQ8_rAMU
|
||||
|
||||
The project focus is a clean REST API and a good user interface. Ruby on Rails is used for the back-end, while React.js and Redux are used for the dynamic front-end. A static front-end for public resources (profiles and statuses) is also provided.
|
||||
|
||||
If you would like, you can [support the development of this project on Patreon][patreon]. Alternatively, you can donate to this BTC address: `17j2g7vpgHhLuXhN4bueZFCvdxxieyRVWd`
|
||||
|
||||
[patreon]: https://www.patreon.com/user?u=619786
|
||||
|
||||
## Resources
|
||||
|
||||
- [List of Mastodon instances](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/List-of-Mastodon-instances.md)
|
||||
- [Use this tool to find Twitter friends on Mastodon](https://mastodon-bridge.herokuapp.com)
|
||||
- [API overview](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md)
|
||||
- [Frequently Asked Questions](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/FAQ.md)
|
||||
- [List of apps](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md)
|
||||
|
||||
## Features
|
||||
|
||||
- **Fully interoperable with GNU social and any OStatus platform**
|
||||
Whatever implements Atom feeds, ActivityStreams, Salmon, WebSub and Webfinger is part of the network
|
||||
- **Real-time timeline updates**
|
||||
See the updates of people you're following appear in real-time in the UI via WebSockets
|
||||
- **Federated thread resolving**
|
||||
If someone you follow replies to a user unknown to the server, the server fetches the full thread so you can view it without leaving the UI
|
||||
- **Media attachments like images and WebM**
|
||||
Upload and view images and WebM videos attached to the updates
|
||||
- **OAuth2 and a straightforward REST API**
|
||||
Mastodon acts as an OAuth2 provider so 3rd party apps can use the API, which is RESTful and simple
|
||||
- **Background processing for long-running tasks**
|
||||
Mastodon tries to be as fast and responsive as possible, so all long-running tasks that can be delegated to background processing, are
|
||||
- **Deployable via Docker**
|
||||
You don't need to mess with dependencies and configuration if you want to try Mastodon, if you have Docker and Docker Compose the deployment is extremely easy
|
||||
|
||||
## Development
|
||||
|
||||
Please follow the [development guide](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md) from the documentation repository.
|
||||
|
||||
## Deployment
|
||||
|
||||
There are guides in the documentation repository for [deploying on various platforms](https://github.com/tootsuite/documentation#running-mastodon).
|
||||
|
||||
## Contributing
|
||||
|
||||
You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository. [Here are the guidelines for code contributions](CONTRIBUTING.md)
|
||||
|
||||
**IRC channel**: #mastodon on irc.freenode.net
|
||||
|
||||
## Extra credits
|
||||
|
||||
- The [Emoji One](https://github.com/Ranks/emojione) pack has been used for the emojis
|
||||
- The error page image courtesy of [Dopatwo](https://www.youtube.com/user/dopatwo)
|
||||
|
||||

|
||||
|
||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
@@ -83,7 +83,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
|
||||
config.vm.provider :virtualbox do |vb|
|
||||
vb.name = "mastodon"
|
||||
vb.customize ["modifyvm", :id, "--memory", "4096"]
|
||||
vb.customize ["modifyvm", :id, "--memory", "2048"]
|
||||
|
||||
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
|
||||
# https://github.com/mitchellh/vagrant/issues/1172
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AboutController < ApplicationController
|
||||
before_action :set_pack
|
||||
before_action :set_body_classes
|
||||
before_action :set_instance_presenter, only: [:show, :more, :terms]
|
||||
|
||||
@@ -22,10 +21,6 @@ class AboutController < ApplicationController
|
||||
|
||||
helper_method :new_user
|
||||
|
||||
def set_pack
|
||||
use_pack action_name == 'show' ? 'about' : 'common'
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
@@ -7,7 +7,6 @@ class AccountsController < ApplicationController
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
@pinned_statuses = []
|
||||
|
||||
if current_account && @account.blocking?(current_account)
|
||||
@@ -15,7 +14,7 @@ class AccountsController < ApplicationController
|
||||
return
|
||||
end
|
||||
|
||||
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
|
||||
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) unless media_requested?
|
||||
@statuses = filtered_statuses.paginate_by_max_id(20, params[:max_id], params[:since_id])
|
||||
@statuses = cache_collection(@statuses, Status)
|
||||
@next_url = next_url unless @statuses.empty?
|
||||
@@ -23,24 +22,17 @@ class AccountsController < ApplicationController
|
||||
|
||||
format.atom do
|
||||
@entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(20, params[:max_id], params[:since_id])
|
||||
render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.feed(@account, @entries.reject { |entry| entry.status.nil? }))
|
||||
render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.feed(@account, @entries.to_a))
|
||||
end
|
||||
|
||||
format.json do
|
||||
render json: @account,
|
||||
serializer: ActivityPub::ActorSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
render json: @account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def show_pinned_statuses?
|
||||
[replies_requested?, media_requested?, params[:max_id].present?, params[:since_id].present?].none?
|
||||
end
|
||||
|
||||
def filtered_statuses
|
||||
default_statuses.tap do |statuses|
|
||||
statuses.merge!(only_media_scope) if media_requested?
|
||||
@@ -49,7 +41,7 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def default_statuses
|
||||
@account.statuses.not_local_only.where(visibility: [:public, :unlisted])
|
||||
@account.statuses.where(visibility: [:public, :unlisted])
|
||||
end
|
||||
|
||||
def only_media_scope
|
||||
|
||||
@@ -9,9 +9,9 @@ class ActivityPub::InboxesController < Api::BaseController
|
||||
if signed_request_account
|
||||
upgrade_account
|
||||
process_payload
|
||||
head 202
|
||||
head 201
|
||||
else
|
||||
[signature_verification_failure_reason, 401]
|
||||
head 202
|
||||
end
|
||||
end
|
||||
|
||||
@@ -26,13 +26,8 @@ class ActivityPub::InboxesController < Api::BaseController
|
||||
end
|
||||
|
||||
def upgrade_account
|
||||
if signed_request_account.ostatus?
|
||||
signed_request_account.update(last_webfingered_at: nil)
|
||||
ResolveRemoteAccountWorker.perform_async(signed_request_account.acct)
|
||||
end
|
||||
|
||||
Pubsubhubbub::UnsubscribeWorker.perform_async(signed_request_account.id) if signed_request_account.subscribed?
|
||||
DeliveryFailureTracker.track_inverse_success!(signed_request_account)
|
||||
return unless signed_request_account.subscribed?
|
||||
Pubsubhubbub::UnsubscribeWorker.perform_async(signed_request_account.id)
|
||||
end
|
||||
|
||||
def process_payload
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class AccountModerationNotesController < BaseController
|
||||
before_action :set_account_moderation_note, only: [:destroy]
|
||||
|
||||
def create
|
||||
authorize AccountModerationNote, :create?
|
||||
|
||||
@account_moderation_note = current_account.account_moderation_notes.new(resource_params)
|
||||
|
||||
if @account_moderation_note.save
|
||||
redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.created_msg')
|
||||
else
|
||||
@account = @account_moderation_note.target_account
|
||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
||||
|
||||
render template: 'admin/accounts/show'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @account_moderation_note, :destroy?
|
||||
@account_moderation_note.destroy!
|
||||
redirect_to admin_account_path(@account_moderation_note.target_account_id), notice: I18n.t('admin.account_moderation_notes.destroyed_msg')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:account_moderation_note).permit(
|
||||
:content,
|
||||
:target_account_id
|
||||
)
|
||||
end
|
||||
|
||||
def set_account_moderation_note
|
||||
@account_moderation_note = AccountModerationNote.find(params[:id])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,57 +2,26 @@
|
||||
|
||||
module Admin
|
||||
class AccountsController < BaseController
|
||||
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :enable, :disable, :memorialize]
|
||||
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload]
|
||||
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
|
||||
before_action :require_local_account!, only: [:enable, :disable, :memorialize]
|
||||
|
||||
def index
|
||||
authorize :account, :index?
|
||||
@accounts = filtered_accounts.page(params[:page])
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @account, :show?
|
||||
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
|
||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
||||
end
|
||||
def show; end
|
||||
|
||||
def subscribe
|
||||
authorize @account, :subscribe?
|
||||
Pubsubhubbub::SubscribeWorker.perform_async(@account.id)
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def unsubscribe
|
||||
authorize @account, :unsubscribe?
|
||||
Pubsubhubbub::UnsubscribeWorker.perform_async(@account.id)
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def memorialize
|
||||
authorize @account, :memorialize?
|
||||
@account.memorialize!
|
||||
log_action :memorialize, @account
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def enable
|
||||
authorize @account.user, :enable?
|
||||
@account.user.enable!
|
||||
log_action :enable, @account.user
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def disable
|
||||
authorize @account.user, :disable?
|
||||
@account.user.disable!
|
||||
log_action :disable, @account.user
|
||||
redirect_to admin_account_path(@account.id)
|
||||
end
|
||||
|
||||
def redownload
|
||||
authorize @account, :redownload?
|
||||
|
||||
@account.reset_avatar!
|
||||
@account.reset_header!
|
||||
@account.save!
|
||||
@@ -70,10 +39,6 @@ module Admin
|
||||
redirect_to admin_account_path(@account.id) if @account.local?
|
||||
end
|
||||
|
||||
def require_local_account!
|
||||
redirect_to admin_account_path(@account.id) unless @account.local? && @account.user.present?
|
||||
end
|
||||
|
||||
def filtered_accounts
|
||||
AccountFilter.new(filter_params).results
|
||||
end
|
||||
@@ -89,8 +54,7 @@ module Admin
|
||||
:username,
|
||||
:display_name,
|
||||
:email,
|
||||
:ip,
|
||||
:staff
|
||||
:ip
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class ActionLogsController < BaseController
|
||||
def index
|
||||
@action_logs = Admin::ActionLog.page(params[:page])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,16 +2,8 @@
|
||||
|
||||
module Admin
|
||||
class BaseController < ApplicationController
|
||||
include Authorization
|
||||
include AccountableConcern
|
||||
before_action :require_admin!
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :require_staff!
|
||||
before_action :set_pack
|
||||
|
||||
def set_pack
|
||||
use_pack 'admin'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,19 +2,15 @@
|
||||
|
||||
module Admin
|
||||
class ConfirmationsController < BaseController
|
||||
before_action :set_user
|
||||
|
||||
def create
|
||||
authorize @user, :confirm?
|
||||
@user.confirm!
|
||||
log_action :confirm, @user
|
||||
account_user.confirm
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user
|
||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||
def account_user
|
||||
Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class CustomEmojisController < BaseController
|
||||
before_action :set_custom_emoji, except: [:index, :new, :create]
|
||||
|
||||
def index
|
||||
authorize :custom_emoji, :index?
|
||||
@custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page])
|
||||
end
|
||||
|
||||
def new
|
||||
authorize :custom_emoji, :create?
|
||||
@custom_emoji = CustomEmoji.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :custom_emoji, :create?
|
||||
|
||||
@custom_emoji = CustomEmoji.new(resource_params)
|
||||
|
||||
if @custom_emoji.save
|
||||
log_action :create, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.created_msg')
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @custom_emoji, :update?
|
||||
|
||||
if @custom_emoji.update(resource_params)
|
||||
log_action :update, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.updated_msg')
|
||||
else
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.update_failed_msg')
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @custom_emoji, :destroy?
|
||||
@custom_emoji.destroy!
|
||||
log_action :destroy, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.destroyed_msg')
|
||||
end
|
||||
|
||||
def copy
|
||||
authorize @custom_emoji, :copy?
|
||||
|
||||
emoji = CustomEmoji.find_or_initialize_by(domain: nil, shortcode: @custom_emoji.shortcode)
|
||||
emoji.image = @custom_emoji.image
|
||||
|
||||
if emoji.save
|
||||
log_action :create, emoji
|
||||
flash[:notice] = I18n.t('admin.custom_emojis.copied_msg')
|
||||
else
|
||||
flash[:alert] = I18n.t('admin.custom_emojis.copy_failed_msg')
|
||||
end
|
||||
|
||||
redirect_to admin_custom_emojis_path(page: params[:page])
|
||||
end
|
||||
|
||||
def enable
|
||||
authorize @custom_emoji, :enable?
|
||||
@custom_emoji.update!(disabled: false)
|
||||
log_action :enable, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.enabled_msg')
|
||||
end
|
||||
|
||||
def disable
|
||||
authorize @custom_emoji, :disable?
|
||||
@custom_emoji.update!(disabled: true)
|
||||
log_action :disable, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.disabled_msg')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_custom_emoji
|
||||
@custom_emoji = CustomEmoji.find(params[:id])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker)
|
||||
end
|
||||
|
||||
def filtered_custom_emojis
|
||||
CustomEmojiFilter.new(filter_params).results
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.permit(
|
||||
:local,
|
||||
:remote,
|
||||
:by_domain,
|
||||
:shortcode
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -5,37 +5,28 @@ module Admin
|
||||
before_action :set_domain_block, only: [:show, :destroy]
|
||||
|
||||
def index
|
||||
authorize :domain_block, :index?
|
||||
@domain_blocks = DomainBlock.page(params[:page])
|
||||
end
|
||||
|
||||
def new
|
||||
authorize :domain_block, :create?
|
||||
@domain_block = DomainBlock.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :domain_block, :create?
|
||||
|
||||
@domain_block = DomainBlock.new(resource_params)
|
||||
|
||||
if @domain_block.save
|
||||
DomainBlockWorker.perform_async(@domain_block.id)
|
||||
log_action :create, @domain_block
|
||||
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.created_msg')
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @domain_block, :show?
|
||||
end
|
||||
def show; end
|
||||
|
||||
def destroy
|
||||
authorize @domain_block, :destroy?
|
||||
UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
|
||||
log_action :destroy, @domain_block
|
||||
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.destroyed_msg')
|
||||
end
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class EmailDomainBlocksController < BaseController
|
||||
before_action :set_email_domain_block, only: [:show, :destroy]
|
||||
|
||||
def index
|
||||
authorize :email_domain_block, :index?
|
||||
@email_domain_blocks = EmailDomainBlock.page(params[:page])
|
||||
end
|
||||
|
||||
def new
|
||||
authorize :email_domain_block, :create?
|
||||
@email_domain_block = EmailDomainBlock.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :email_domain_block, :create?
|
||||
|
||||
@email_domain_block = EmailDomainBlock.new(resource_params)
|
||||
|
||||
if @email_domain_block.save
|
||||
log_action :create, @email_domain_block
|
||||
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.created_msg')
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @email_domain_block, :destroy?
|
||||
@email_domain_block.destroy!
|
||||
log_action :destroy, @email_domain_block
|
||||
redirect_to admin_email_domain_blocks_path, notice: I18n.t('admin.email_domain_blocks.destroyed_msg')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_email_domain_block
|
||||
@email_domain_block = EmailDomainBlock.find(params[:id])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:email_domain_block).permit(:domain)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,12 +3,10 @@
|
||||
module Admin
|
||||
class InstancesController < BaseController
|
||||
def index
|
||||
authorize :instance, :index?
|
||||
@instances = ordered_instances
|
||||
end
|
||||
|
||||
def resubscribe
|
||||
authorize :instance, :resubscribe?
|
||||
params.require(:by_domain)
|
||||
Pubsubhubbub::SubscribeWorker.push_bulk(subscribeable_accounts.pluck(:id))
|
||||
redirect_to admin_instances_path
|
||||
@@ -16,12 +14,8 @@ module Admin
|
||||
|
||||
private
|
||||
|
||||
def filtered_instances
|
||||
InstanceFilter.new(filter_params).results
|
||||
end
|
||||
|
||||
def paginated_instances
|
||||
filtered_instances.page(params[:page])
|
||||
Account.remote.by_domain_accounts.page(params[:page])
|
||||
end
|
||||
|
||||
helper_method :paginated_instances
|
||||
@@ -33,11 +27,5 @@ module Admin
|
||||
def subscribeable_accounts
|
||||
Account.with_followers.remote.where(domain: params[:by_domain])
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.permit(
|
||||
:domain_name
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class InvitesController < BaseController
|
||||
def index
|
||||
authorize :invite, :index?
|
||||
|
||||
@invites = filtered_invites.includes(user: :account).page(params[:page])
|
||||
@invite = Invite.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :invite, :create?
|
||||
|
||||
@invite = Invite.new(resource_params)
|
||||
@invite.user = current_user
|
||||
|
||||
if @invite.save
|
||||
redirect_to admin_invites_path
|
||||
else
|
||||
@invites = Invite.page(params[:page])
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@invite = Invite.find(params[:id])
|
||||
authorize @invite, :destroy?
|
||||
@invite.expire!
|
||||
redirect_to admin_invites_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:invite).permit(:max_uses, :expires_in)
|
||||
end
|
||||
|
||||
def filtered_invites
|
||||
InviteFilter.new(filter_params).results
|
||||
end
|
||||
|
||||
def filter_params
|
||||
params.permit(:available, :expired)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,29 +2,26 @@
|
||||
|
||||
module Admin
|
||||
class ReportedStatusesController < BaseController
|
||||
include Authorization
|
||||
|
||||
before_action :set_report
|
||||
before_action :set_status, only: [:update, :destroy]
|
||||
|
||||
def create
|
||||
authorize :status, :update?
|
||||
|
||||
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account))
|
||||
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
||||
@form = Form::StatusBatch.new(form_status_batch_params)
|
||||
flash[:alert] = t('admin.statuses.failed_to_execute') unless @form.save
|
||||
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @status, :update?
|
||||
@status.update!(status_params)
|
||||
log_action :update, @status
|
||||
@status.update(status_params)
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @status, :destroy?
|
||||
RemovalWorker.perform_async(@status.id)
|
||||
log_action :destroy, @status
|
||||
render json: @status
|
||||
end
|
||||
|
||||
|
||||
@@ -5,17 +5,14 @@ module Admin
|
||||
before_action :set_report, except: [:index]
|
||||
|
||||
def index
|
||||
authorize :report, :index?
|
||||
@reports = filtered_reports.page(params[:page])
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @report, :show?
|
||||
@form = Form::StatusBatch.new
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @report, :update?
|
||||
process_report
|
||||
redirect_to admin_report_path(@report)
|
||||
end
|
||||
@@ -25,17 +22,12 @@ module Admin
|
||||
def process_report
|
||||
case params[:outcome].to_s
|
||||
when 'resolve'
|
||||
@report.update!(action_taken_by_current_attributes)
|
||||
log_action :resolve, @report
|
||||
@report.update(action_taken_by_current_attributes)
|
||||
when 'suspend'
|
||||
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
||||
log_action :resolve, @report
|
||||
log_action :suspend, @report.target_account
|
||||
resolve_all_target_account_reports
|
||||
when 'silence'
|
||||
@report.target_account.update!(silenced: true)
|
||||
log_action :resolve, @report
|
||||
log_action :silence, @report.target_account
|
||||
@report.target_account.update(silenced: true)
|
||||
resolve_all_target_account_reports
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound
|
||||
|
||||
@@ -2,19 +2,17 @@
|
||||
|
||||
module Admin
|
||||
class ResetsController < BaseController
|
||||
before_action :set_user
|
||||
before_action :set_account
|
||||
|
||||
def create
|
||||
authorize @user, :reset_password?
|
||||
@user.send_reset_password_instructions
|
||||
log_action :reset_password, @user
|
||||
@account.user.send_reset_password_instructions
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user
|
||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||
def set_account
|
||||
@account = Account.find(params[:account_id])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Admin
|
||||
class RolesController < BaseController
|
||||
before_action :set_user
|
||||
|
||||
def promote
|
||||
authorize @user, :promote?
|
||||
@user.promote!
|
||||
log_action :promote, @user
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
def demote
|
||||
authorize @user, :demote?
|
||||
@user.demote!
|
||||
log_action :demote, @user
|
||||
redirect_to admin_account_path(@user.account_id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user
|
||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -13,40 +13,23 @@ module Admin
|
||||
closed_registrations_message
|
||||
open_deletion
|
||||
timeline_preview
|
||||
show_staff_badge
|
||||
bootstrap_timeline_accounts
|
||||
thumbnail
|
||||
min_invite_role
|
||||
).freeze
|
||||
|
||||
BOOLEAN_SETTINGS = %w(
|
||||
open_registrations
|
||||
open_deletion
|
||||
timeline_preview
|
||||
show_staff_badge
|
||||
).freeze
|
||||
|
||||
UPLOAD_SETTINGS = %w(
|
||||
thumbnail
|
||||
).freeze
|
||||
|
||||
def edit
|
||||
authorize :settings, :show?
|
||||
@admin_settings = Form::AdminSettings.new
|
||||
end
|
||||
|
||||
def update
|
||||
authorize :settings, :update?
|
||||
|
||||
settings_params.each do |key, value|
|
||||
if UPLOAD_SETTINGS.include?(key)
|
||||
upload = SiteUpload.where(var: key).first_or_initialize(var: key)
|
||||
upload.update(file: value)
|
||||
else
|
||||
setting = Setting.where(var: key).first_or_initialize(var: key)
|
||||
setting.update(value: value_for_update(key, value))
|
||||
end
|
||||
end
|
||||
|
||||
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
||||
redirect_to edit_admin_settings_path
|
||||
|
||||
@@ -5,16 +5,12 @@ module Admin
|
||||
before_action :set_account
|
||||
|
||||
def create
|
||||
authorize @account, :silence?
|
||||
@account.update!(silenced: true)
|
||||
log_action :silence, @account
|
||||
@account.update(silenced: true)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @account, :unsilence?
|
||||
@account.update!(silenced: false)
|
||||
log_action :unsilence, @account
|
||||
@account.update(silenced: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
module Admin
|
||||
class StatusesController < BaseController
|
||||
include Authorization
|
||||
|
||||
helper_method :current_params
|
||||
|
||||
before_action :set_account
|
||||
@@ -10,39 +12,31 @@ module Admin
|
||||
PER_PAGE = 20
|
||||
|
||||
def index
|
||||
authorize :status, :index?
|
||||
|
||||
@statuses = @account.statuses
|
||||
|
||||
if params[:media]
|
||||
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).distinct
|
||||
@statuses.merge!(Status.where(id: account_media_status_ids))
|
||||
end
|
||||
|
||||
@statuses = @statuses.preload(:media_attachments, :mentions).page(params[:page]).per(PER_PAGE)
|
||||
|
||||
@form = Form::StatusBatch.new
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :status, :update?
|
||||
|
||||
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account))
|
||||
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
||||
@form = Form::StatusBatch.new(form_status_batch_params)
|
||||
flash[:alert] = t('admin.statuses.failed_to_execute') unless @form.save
|
||||
|
||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @status, :update?
|
||||
@status.update!(status_params)
|
||||
log_action :update, @status
|
||||
@status.update(status_params)
|
||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @status, :destroy?
|
||||
RemovalWorker.perform_async(@status.id)
|
||||
log_action :destroy, @status
|
||||
render json: @status
|
||||
end
|
||||
|
||||
@@ -66,7 +60,6 @@ module Admin
|
||||
|
||||
def current_params
|
||||
page = (params[:page] || 1).to_i
|
||||
|
||||
{
|
||||
media: params[:media],
|
||||
page: page > 1 && page,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
module Admin
|
||||
class SubscriptionsController < BaseController
|
||||
def index
|
||||
authorize :subscription, :index?
|
||||
@subscriptions = ordered_subscriptions.page(requested_page)
|
||||
end
|
||||
|
||||
|
||||
@@ -5,16 +5,12 @@ module Admin
|
||||
before_action :set_account
|
||||
|
||||
def create
|
||||
authorize @account, :suspend?
|
||||
Admin::SuspensionWorker.perform_async(@account.id)
|
||||
log_action :suspend, @account
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @account, :unsuspend?
|
||||
@account.unsuspend!
|
||||
log_action :unsuspend, @account
|
||||
@account.update(suspended: false)
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -5,9 +5,7 @@ module Admin
|
||||
before_action :set_user
|
||||
|
||||
def destroy
|
||||
authorize @user, :disable_2fa?
|
||||
@user.disable_two_factor!
|
||||
log_action :disable_2fa, @user
|
||||
redirect_to admin_accounts_path
|
||||
end
|
||||
|
||||
|
||||
@@ -72,4 +72,19 @@ class Api::BaseController < ApplicationController
|
||||
def render_empty
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
||||
def set_maps(statuses) # rubocop:disable Style/AccessorMethodName
|
||||
if current_account.nil?
|
||||
@reblogs_map = {}
|
||||
@favourites_map = {}
|
||||
@mutes_map = {}
|
||||
return
|
||||
end
|
||||
|
||||
status_ids = statuses.compact.flat_map { |s| [s.id, s.reblog_of_id] }.uniq
|
||||
conversation_ids = statuses.compact.map(&:conversation_id).compact.uniq
|
||||
@reblogs_map = Status.reblogs_map(status_ids, current_account)
|
||||
@favourites_map = Status.favourites_map(status_ids, current_account)
|
||||
@mutes_map = Status.mutes_map(conversation_ids, current_account)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,11 +7,9 @@ class Api::SalmonController < Api::BaseController
|
||||
def update
|
||||
if verify_payload?
|
||||
process_salmon
|
||||
head 202
|
||||
elsif payload.present?
|
||||
[signature_verification_failure_reason, 401]
|
||||
head 201
|
||||
else
|
||||
head 400
|
||||
head 202
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::ListsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
before_action :set_account
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@lists = @account.lists.where(account: current_account)
|
||||
render json: @lists, each_serializer: REST::ListSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = Account.find(params[:account_id])
|
||||
end
|
||||
end
|
||||
@@ -7,10 +7,7 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
accounts = Account.where(id: account_ids).select('id')
|
||||
# .where doesn't guarantee that our results are in the same order
|
||||
# we requested them, so return the "right" order to the requestor.
|
||||
@accounts = accounts.index_by(&:id).values_at(*account_ids)
|
||||
@accounts = Account.where(id: account_ids).select('id')
|
||||
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
|
||||
end
|
||||
|
||||
|
||||
@@ -17,13 +17,12 @@ class Api::V1::Accounts::SearchController < Api::BaseController
|
||||
AccountSearchService.new.call(
|
||||
params[:q],
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
current_account,
|
||||
resolve: truthy_param?(:resolve),
|
||||
following: truthy_param?(:following)
|
||||
resolving_search?,
|
||||
current_account
|
||||
)
|
||||
end
|
||||
|
||||
def truthy_param?(key)
|
||||
params[key] == 'true'
|
||||
def resolving_search?
|
||||
params[:resolve] == 'true'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,11 +13,8 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
end
|
||||
|
||||
def follow
|
||||
FollowService.new.call(current_user.account, @account.acct, reblogs: params[:reblogs])
|
||||
|
||||
options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: params[:reblogs] } }, requested_map: { @account.id => false } }
|
||||
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
|
||||
FollowService.new.call(current_user.account, @account.acct)
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
||||
end
|
||||
|
||||
def block
|
||||
@@ -26,7 +23,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
end
|
||||
|
||||
def mute
|
||||
MuteService.new.call(current_user.account, @account, notifications: params[:notifications])
|
||||
MuteService.new.call(current_user.account, @account)
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
||||
end
|
||||
|
||||
@@ -51,7 +48,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
@account = Account.find(params[:id])
|
||||
end
|
||||
|
||||
def relationships(**options)
|
||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
|
||||
def relationships
|
||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Apps::CredentialsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
|
||||
respond_to :json
|
||||
|
||||
def show
|
||||
render json: doorkeeper_token.application, serializer: REST::StatusSerializer::ApplicationSerializer
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::AppsController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def create
|
||||
@app = Doorkeeper::Application.create!(application_options)
|
||||
render json: @app, serializer: REST::ApplicationSerializer
|
||||
|
||||
@@ -15,13 +15,15 @@ class Api::V1::BlocksController < Api::BaseController
|
||||
private
|
||||
|
||||
def load_accounts
|
||||
paginated_blocks.map(&:target_account)
|
||||
default_accounts.merge(paginated_blocks).to_a
|
||||
end
|
||||
|
||||
def default_accounts
|
||||
Account.includes(:blocked_by).references(:blocked_by)
|
||||
end
|
||||
|
||||
def paginated_blocks
|
||||
@paginated_blocks ||= Block.eager_load(:target_account)
|
||||
.where(account: current_account)
|
||||
.paginate_by_max_id(
|
||||
Block.where(account: current_account).paginate_by_max_id(
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
@@ -39,21 +41,21 @@ class Api::V1::BlocksController < Api::BaseController
|
||||
end
|
||||
|
||||
def prev_path
|
||||
unless paginated_blocks.empty?
|
||||
unless @accounts.empty?
|
||||
api_v1_blocks_url pagination_params(since_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
paginated_blocks.last.id
|
||||
@accounts.last.blocked_by_ids.last
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
paginated_blocks.first.id
|
||||
@accounts.first.blocked_by_ids.first
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
paginated_blocks.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::CustomEmojisController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
render json: CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer
|
||||
end
|
||||
end
|
||||
@@ -10,12 +10,6 @@ class Api::V1::FollowsController < Api::BaseController
|
||||
raise ActiveRecord::RecordNotFound if follow_params[:uri].blank?
|
||||
|
||||
@account = FollowService.new.call(current_user.account, target_uri).try(:target_account)
|
||||
|
||||
if @account.nil?
|
||||
username, domain = target_uri.split('@')
|
||||
@account = Account.find_remote!(username, domain)
|
||||
end
|
||||
|
||||
render json: @account, serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Lists::AccountsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:show]
|
||||
before_action -> { doorkeeper_authorize! :write }, except: [:show]
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_list
|
||||
|
||||
after_action :insert_pagination_headers, only: :show
|
||||
|
||||
def show
|
||||
@accounts = load_accounts
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
ApplicationRecord.transaction do
|
||||
list_accounts.each do |account|
|
||||
@list.accounts << account
|
||||
end
|
||||
end
|
||||
|
||||
render_empty
|
||||
end
|
||||
|
||||
def destroy
|
||||
ListAccount.where(list: @list, account_id: account_ids).destroy_all
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_list
|
||||
@list = List.where(account: current_account).find(params[:list_id])
|
||||
end
|
||||
|
||||
def load_accounts
|
||||
if unlimited?
|
||||
@list.accounts.all
|
||||
else
|
||||
@list.accounts.paginate_by_max_id(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:max_id], params[:since_id])
|
||||
end
|
||||
end
|
||||
|
||||
def list_accounts
|
||||
Account.find(account_ids)
|
||||
end
|
||||
|
||||
def account_ids
|
||||
Array(resource_params[:account_ids])
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(account_ids: [])
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
def next_path
|
||||
return if unlimited?
|
||||
|
||||
if records_continue?
|
||||
api_v1_list_accounts_url pagination_params(max_id: pagination_max_id)
|
||||
end
|
||||
end
|
||||
|
||||
def prev_path
|
||||
return if unlimited?
|
||||
|
||||
unless @accounts.empty?
|
||||
api_v1_list_accounts_url pagination_params(since_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
@accounts.last.id
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
@accounts.first.id
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def unlimited?
|
||||
params[:limit] == '0'
|
||||
end
|
||||
end
|
||||
@@ -1,43 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::ListsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:index, :show]
|
||||
before_action -> { doorkeeper_authorize! :write }, except: [:index, :show]
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_list, except: [:index, :create]
|
||||
|
||||
def index
|
||||
@lists = List.where(account: current_account).all
|
||||
render json: @lists, each_serializer: REST::ListSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render json: @list, serializer: REST::ListSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
@list = List.create!(list_params.merge(account: current_account))
|
||||
render json: @list, serializer: REST::ListSerializer
|
||||
end
|
||||
|
||||
def update
|
||||
@list.update!(list_params)
|
||||
render json: @list, serializer: REST::ListSerializer
|
||||
end
|
||||
|
||||
def destroy
|
||||
@list.destroy!
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_list
|
||||
@list = List.where(account: current_account).find(params[:id])
|
||||
end
|
||||
|
||||
def list_params
|
||||
params.permit(:title)
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@ class Api::V1::MediaController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def create
|
||||
@media = current_account.media_attachments.create!(media_params)
|
||||
@media = current_account.media_attachments.create!(file: media_params[:file])
|
||||
render json: @media, serializer: REST::MediaAttachmentSerializer
|
||||
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
|
||||
render json: file_type_error, status: 422
|
||||
@@ -18,16 +18,10 @@ class Api::V1::MediaController < Api::BaseController
|
||||
render json: processing_error, status: 500
|
||||
end
|
||||
|
||||
def update
|
||||
@media = current_account.media_attachments.where(status_id: nil).find(params[:id])
|
||||
@media.update!(media_params)
|
||||
render json: @media, serializer: REST::MediaAttachmentSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def media_params
|
||||
params.permit(:file, :description)
|
||||
params.permit(:file)
|
||||
end
|
||||
|
||||
def file_type_error
|
||||
|
||||
@@ -8,15 +8,10 @@ class Api::V1::MutesController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@data = @accounts = load_accounts
|
||||
@accounts = load_accounts
|
||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
def details
|
||||
@data = @mutes = load_mutes
|
||||
render json: @mutes, each_serializer: REST::MuteSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_accounts
|
||||
@@ -27,10 +22,6 @@ class Api::V1::MutesController < Api::BaseController
|
||||
Account.includes(:muted_by).references(:muted_by)
|
||||
end
|
||||
|
||||
def load_mutes
|
||||
paginated_mutes.includes(:account, :target_account).to_a
|
||||
end
|
||||
|
||||
def paginated_mutes
|
||||
Mute.where(account: current_account).paginate_by_max_id(
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
@@ -45,34 +36,26 @@ class Api::V1::MutesController < Api::BaseController
|
||||
|
||||
def next_path
|
||||
if records_continue?
|
||||
url_for pagination_params(max_id: pagination_max_id)
|
||||
api_v1_mutes_url pagination_params(max_id: pagination_max_id)
|
||||
end
|
||||
end
|
||||
|
||||
def prev_path
|
||||
unless@data.empty?
|
||||
url_for pagination_params(since_id: pagination_since_id)
|
||||
unless @accounts.empty?
|
||||
api_v1_mutes_url pagination_params(since_id: pagination_since_id)
|
||||
end
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
if params[:action] == "details"
|
||||
@mutes.last.id
|
||||
else
|
||||
@accounts.last.muted_by_ids.last
|
||||
end
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
if params[:action] == "details"
|
||||
@mutes.first.id
|
||||
else
|
||||
@accounts.first.muted_by_ids.first
|
||||
end
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
@data.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
|
||||
@@ -24,20 +24,11 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||
render_empty
|
||||
end
|
||||
|
||||
def destroy
|
||||
dismiss
|
||||
end
|
||||
|
||||
def dismiss
|
||||
current_account.notifications.find_by!(id: params[:id]).destroy!
|
||||
render_empty
|
||||
end
|
||||
|
||||
def destroy_multiple
|
||||
current_account.notifications.where(id: params[:ids]).destroy_all
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_notifications
|
||||
|
||||
@@ -19,7 +19,7 @@ class Api::V1::ReportsController < Api::BaseController
|
||||
comment: report_params[:comment]
|
||||
)
|
||||
|
||||
User.staff.includes(:account).each { |u| AdminMailer.new_report(u.account, @report).deliver_later }
|
||||
User.admins.includes(:account).each { |u| AdminMailer.new_report(u.account, @report).deliver_later }
|
||||
|
||||
render json: @report, serializer: REST::ReportSerializer
|
||||
end
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::SearchController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
RESULTS_LIMIT = 10
|
||||
RESULTS_LIMIT = 5
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
@@ -11,24 +9,12 @@ class Api::V1::SearchController < Api::BaseController
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
@search = Search.new(search)
|
||||
@search = Search.new(search_results)
|
||||
render json: @search, serializer: REST::SearchSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def search
|
||||
search_results.tap do |search|
|
||||
search[:statuses].keep_if do |status|
|
||||
begin
|
||||
authorize status, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def search_results
|
||||
SearchService.new.call(
|
||||
params[:q],
|
||||
|
||||
@@ -42,7 +42,6 @@ class Api::V1::StatusesController < Api::BaseController
|
||||
@status = PostStatusService.new.call(current_user.account,
|
||||
status_params[:status],
|
||||
status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
|
||||
local_only: status_params[:local_only],
|
||||
media_ids: status_params[:media_ids],
|
||||
sensitive: status_params[:sensitive],
|
||||
spoiler_text: status_params[:spoiler_text],
|
||||
@@ -73,7 +72,7 @@ class Api::V1::StatusesController < Api::BaseController
|
||||
end
|
||||
|
||||
def status_params
|
||||
params.permit(:status, :in_reply_to_id, :local_only, :sensitive, :spoiler_text, :visibility, media_ids: [])
|
||||
params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: [])
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Timelines::DirectController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }, only: [:show]
|
||||
before_action :require_user!, only: [:show]
|
||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||
|
||||
respond_to :json
|
||||
|
||||
def show
|
||||
@statuses = load_statuses
|
||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_statuses
|
||||
cached_direct_statuses
|
||||
end
|
||||
|
||||
def cached_direct_statuses
|
||||
cache_collection direct_statuses, Status
|
||||
end
|
||||
|
||||
def direct_statuses
|
||||
direct_timeline_statuses.paginate_by_max_id(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
)
|
||||
end
|
||||
|
||||
def direct_timeline_statuses
|
||||
Status.as_direct_timeline(current_account)
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:local, :limit).merge(core_params)
|
||||
end
|
||||
|
||||
def next_path
|
||||
api_v1_timelines_direct_url pagination_params(max_id: pagination_max_id)
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_timelines_direct_url pagination_params(since_id: pagination_since_id)
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
@statuses.last.id
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
@statuses.first.id
|
||||
end
|
||||
end
|
||||
@@ -31,7 +31,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||
end
|
||||
|
||||
def account_home_feed
|
||||
HomeFeed.new(current_account)
|
||||
Feed.new(:home, current_account)
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Timelines::ListController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :read }
|
||||
before_action :require_user!
|
||||
before_action :set_list
|
||||
before_action :set_statuses
|
||||
|
||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||
|
||||
def show
|
||||
render json: @statuses,
|
||||
each_serializer: REST::StatusSerializer,
|
||||
relationships: StatusRelationshipsPresenter.new(@statuses, current_user.account_id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_list
|
||||
@list = List.where(account: current_account).find(params[:id])
|
||||
end
|
||||
|
||||
def set_statuses
|
||||
@statuses = cached_list_statuses
|
||||
end
|
||||
|
||||
def cached_list_statuses
|
||||
cache_collection list_statuses, Status
|
||||
end
|
||||
|
||||
def list_statuses
|
||||
list_feed.get(
|
||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
)
|
||||
end
|
||||
|
||||
def list_feed
|
||||
ListFeed.new(@list)
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.permit(:limit).merge(core_params)
|
||||
end
|
||||
|
||||
def next_path
|
||||
api_v1_timelines_list_url params[:id], pagination_params(max_id: pagination_max_id)
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_timelines_list_url params[:id], pagination_params(since_id: pagination_since_id)
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
@statuses.last.id
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
@statuses.first.id
|
||||
end
|
||||
end
|
||||
@@ -28,8 +28,6 @@ class Api::Web::PushSubscriptionsController < Api::BaseController
|
||||
},
|
||||
}
|
||||
|
||||
data.deep_merge!(params[:data]) if params[:data]
|
||||
|
||||
web_subscription = ::Web::PushSubscription.create!(
|
||||
endpoint: params[:subscription][:endpoint],
|
||||
key_p256dh: params[:subscription][:keys][:p256dh],
|
||||
|
||||
@@ -12,14 +12,11 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
helper_method :current_account
|
||||
helper_method :current_session
|
||||
helper_method :current_flavour
|
||||
helper_method :current_skin
|
||||
helper_method :single_user_mode?
|
||||
|
||||
rescue_from ActionController::RoutingError, with: :not_found
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
|
||||
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
||||
|
||||
before_action :store_current_location, except: :raise_not_found, unless: :devise_controller?
|
||||
before_action :check_suspension, if: :user_signed_in?
|
||||
@@ -42,10 +39,6 @@ class ApplicationController < ActionController::Base
|
||||
redirect_to root_path unless current_user&.admin?
|
||||
end
|
||||
|
||||
def require_staff!
|
||||
redirect_to root_path unless current_user&.staff?
|
||||
end
|
||||
|
||||
def check_suspension
|
||||
forbidden if current_user.account.suspended?
|
||||
end
|
||||
@@ -54,75 +47,6 @@ class ApplicationController < ActionController::Base
|
||||
new_user_session_path
|
||||
end
|
||||
|
||||
def pack(data, pack_name, skin = 'default')
|
||||
return nil unless pack?(data, pack_name)
|
||||
pack_data = {
|
||||
common: pack_name == 'common' ? nil : resolve_pack(data['name'] ? Themes.instance.flavour(current_flavour) : Themes.instance.core, 'common', skin),
|
||||
flavour: data['name'],
|
||||
pack: pack_name,
|
||||
preload: nil,
|
||||
skin: nil,
|
||||
supported_locales: data['locales'],
|
||||
}
|
||||
if data['pack'][pack_name].is_a?(Hash)
|
||||
pack_data[:common] = nil if data['pack'][pack_name]['use_common'] == false
|
||||
pack_data[:pack] = nil unless data['pack'][pack_name]['filename']
|
||||
if data['pack'][pack_name]['preload']
|
||||
pack_data[:preload] = [data['pack'][pack_name]['preload']] if data['pack'][pack_name]['preload'].is_a?(String)
|
||||
pack_data[:preload] = data['pack'][pack_name]['preload'] if data['pack'][pack_name]['preload'].is_a?(Array)
|
||||
end
|
||||
if skin != 'default' && data['skin'][skin]
|
||||
pack_data[:skin] = skin if data['skin'][skin].include?(pack_name)
|
||||
else # default skin
|
||||
pack_data[:skin] = 'default' if data['pack'][pack_name]['stylesheet']
|
||||
end
|
||||
end
|
||||
pack_data
|
||||
end
|
||||
|
||||
def pack?(data, pack_name)
|
||||
if data['pack'].is_a?(Hash) && data['pack'].key?(pack_name)
|
||||
return true if data['pack'][pack_name].is_a?(String) || data['pack'][pack_name].is_a?(Hash)
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def nil_pack(data, pack_name, skin = 'default')
|
||||
{
|
||||
common: pack_name == 'common' ? nil : resolve_pack(data['name'] ? Themes.instance.flavour(current_flavour) : Themes.instance.core, 'common', skin),
|
||||
flavour: data['name'],
|
||||
pack: nil,
|
||||
preload: nil,
|
||||
skin: nil,
|
||||
supported_locales: data['locales'],
|
||||
}
|
||||
end
|
||||
|
||||
def resolve_pack(data, pack_name, skin = 'default')
|
||||
result = pack(data, pack_name, skin)
|
||||
unless result
|
||||
if data['name'] && data.key?('fallback')
|
||||
if data['fallback'].nil?
|
||||
return nil_pack(data, pack_name, skin)
|
||||
elsif data['fallback'].is_a?(String) && Themes.instance.flavour(data['fallback'])
|
||||
return resolve_pack(Themes.instance.flavour(data['fallback']), pack_name)
|
||||
elsif data['fallback'].is_a?(Array)
|
||||
data['fallback'].each do |fallback|
|
||||
return resolve_pack(Themes.instance.flavour(fallback), pack_name) if Themes.instance.flavour(fallback)
|
||||
end
|
||||
end
|
||||
return nil_pack(data, pack_name, skin)
|
||||
end
|
||||
return data.key?('name') && data['name'] != Setting.default_settings['flavour'] ? resolve_pack(Themes.instance.flavour(Setting.default_settings['flavour']), pack_name) : nil_pack(data, pack_name, skin)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def use_pack(pack_name)
|
||||
@core = resolve_pack(Themes.instance.core, pack_name)
|
||||
@theme = resolve_pack(Themes.instance.flavour(current_flavour), pack_name, current_skin)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def forbidden
|
||||
@@ -153,16 +77,6 @@ class ApplicationController < ActionController::Base
|
||||
@current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id'])
|
||||
end
|
||||
|
||||
def current_flavour
|
||||
return Setting.default_settings['flavour'] unless Themes.instance.flavours.include? current_user&.setting_flavour
|
||||
current_user.setting_flavour
|
||||
end
|
||||
|
||||
def current_skin
|
||||
return 'default' unless Themes.instance.skins_for(current_flavour).include? current_user&.setting_skin
|
||||
current_user.setting_skin
|
||||
end
|
||||
|
||||
def cache_collection(raw, klass)
|
||||
return raw unless klass.respond_to?(:with_includes)
|
||||
|
||||
@@ -179,7 +93,7 @@ class ApplicationController < ActionController::Base
|
||||
unless uncached_ids.empty?
|
||||
uncached = klass.where(id: uncached_ids).with_includes.map { |item| [item.id, item] }.to_h
|
||||
|
||||
uncached.each_value do |item|
|
||||
uncached.values.each do |item|
|
||||
Rails.cache.write(item.cache_key, item)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,17 +2,4 @@
|
||||
|
||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||
layout 'auth'
|
||||
before_action :set_pack
|
||||
|
||||
def show
|
||||
super do |user|
|
||||
BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'auth'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
class Auth::PasswordsController < Devise::PasswordsController
|
||||
before_action :check_validity_of_reset_password_token, only: :edit
|
||||
before_action :set_pack
|
||||
|
||||
layout 'auth'
|
||||
|
||||
@@ -18,8 +17,4 @@ class Auth::PasswordsController < Devise::PasswordsController
|
||||
def reset_password_token_is_valid?
|
||||
resource_class.with_reset_password_token(params[:reset_password_token]).present?
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'auth'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,9 +5,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
before_action :check_enabled_registrations, only: [:new, :create]
|
||||
before_action :configure_sign_up_params, only: [:create]
|
||||
before_action :set_pack
|
||||
before_action :set_sessions, only: [:edit, :update]
|
||||
before_action :set_instance_presenter, only: [:new, :create, :update]
|
||||
|
||||
def destroy
|
||||
not_found
|
||||
@@ -17,16 +15,13 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
|
||||
def build_resource(hash = nil)
|
||||
super(hash)
|
||||
|
||||
resource.locale = I18n.locale
|
||||
resource.invite_code = params[:invite_code] if resource.invite_code.blank?
|
||||
|
||||
resource.build_account if resource.account.nil?
|
||||
end
|
||||
|
||||
def configure_sign_up_params
|
||||
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
||||
u.permit({ account_attributes: [:username] }, :email, :password, :password_confirmation, :invite_code)
|
||||
u.permit({ account_attributes: [:username] }, :email, :password, :password_confirmation)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,31 +34,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
end
|
||||
|
||||
def check_enabled_registrations
|
||||
redirect_to root_path if single_user_mode? || !allowed_registrations?
|
||||
end
|
||||
|
||||
def allowed_registrations?
|
||||
Setting.open_registrations || (invite_code.present? && Invite.find_by(code: invite_code)&.valid_for_use?)
|
||||
end
|
||||
|
||||
def invite_code
|
||||
if params[:user]
|
||||
params[:user][:invite_code]
|
||||
else
|
||||
params[:invite_code]
|
||||
end
|
||||
redirect_to root_path if single_user_mode? || !Setting.open_registrations
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack %w(edit update).include?(action_name) ? 'admin' : 'auth'
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
def determine_layout
|
||||
%w(edit update).include?(action_name) ? 'admin' : 'auth'
|
||||
end
|
||||
|
||||
@@ -8,8 +8,6 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
skip_before_action :require_no_authentication, only: [:create]
|
||||
skip_before_action :check_suspension, only: [:destroy]
|
||||
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
||||
before_action :set_instance_presenter, only: [:new]
|
||||
before_action :set_pack
|
||||
|
||||
def create
|
||||
super do |resource|
|
||||
@@ -63,7 +61,7 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
|
||||
if user_params[:otp_attempt].present? && session[:otp_user_id]
|
||||
authenticate_with_two_factor_via_otp(user)
|
||||
elsif user&.valid_password?(user_params[:password])
|
||||
elsif user && user.valid_password?(user_params[:password])
|
||||
prompt_for_two_factor(user)
|
||||
end
|
||||
end
|
||||
@@ -86,14 +84,6 @@ class Auth::SessionsController < Devise::SessionsController
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'auth'
|
||||
end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
def home_paths(resource)
|
||||
paths = [about_path]
|
||||
if single_user_mode? && resource.is_a?(User)
|
||||
|
||||
@@ -4,7 +4,6 @@ class AuthorizeFollowsController < ApplicationController
|
||||
layout 'modal'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
|
||||
def show
|
||||
@account = located_account || render(:error)
|
||||
@@ -24,10 +23,6 @@ class AuthorizeFollowsController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'modal'
|
||||
end
|
||||
|
||||
def follow_attempt
|
||||
FollowService.new.call(current_account, acct_without_prefix)
|
||||
end
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module AccountableConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def log_action(action, target)
|
||||
Admin::ActionLog.create(account: current_account, action: action, target: target)
|
||||
end
|
||||
end
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
module Authorization
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include Pundit
|
||||
|
||||
def pundit_user
|
||||
|
||||
@@ -44,8 +44,7 @@ module RateLimitHeaders
|
||||
end
|
||||
|
||||
def api_throttle_data
|
||||
most_limited_type, = request.env['rack.attack.throttle_data'].min_by { |_, v| v[:limit] }
|
||||
request.env['rack.attack.throttle_data'][most_limited_type]
|
||||
request.env['rack.attack.throttle_data']['api']
|
||||
end
|
||||
|
||||
def request_time
|
||||
|
||||
@@ -9,15 +9,10 @@ module SignatureVerification
|
||||
request.headers['Signature'].present?
|
||||
end
|
||||
|
||||
def signature_verification_failure_reason
|
||||
return @signature_verification_failure_reason if defined?(@signature_verification_failure_reason)
|
||||
end
|
||||
|
||||
def signed_request_account
|
||||
return @signed_request_account if defined?(@signed_request_account)
|
||||
|
||||
unless signed_request?
|
||||
@signature_verification_failure_reason = 'Request not signed'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
@@ -32,7 +27,6 @@ module SignatureVerification
|
||||
end
|
||||
|
||||
if incompatible_signature?(signature_params)
|
||||
@signature_verification_failure_reason = 'Incompatible request signature'
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
@@ -40,7 +34,6 @@ module SignatureVerification
|
||||
account = account_from_key_id(signature_params['keyId'])
|
||||
|
||||
if account.nil?
|
||||
@signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
|
||||
@signed_request_account = nil
|
||||
return
|
||||
end
|
||||
@@ -48,21 +41,10 @@ module SignatureVerification
|
||||
signature = Base64.decode64(signature_params['signature'])
|
||||
compare_signed_string = build_signed_string(signature_params['headers'])
|
||||
|
||||
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
|
||||
@signed_request_account = account
|
||||
@signed_request_account
|
||||
elsif account.possibly_stale?
|
||||
account = account.refresh!
|
||||
|
||||
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
|
||||
@signed_request_account = account
|
||||
@signed_request_account
|
||||
else
|
||||
@signed_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signed_request_account = nil
|
||||
end
|
||||
else
|
||||
@signed_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
|
||||
@signed_request_account = nil
|
||||
end
|
||||
end
|
||||
@@ -117,7 +99,7 @@ module SignatureVerification
|
||||
ResolveRemoteAccountService.new.call(key_id.gsub(/\Aacct:/, ''))
|
||||
elsif !ActivityPub::TagManager.instance.local_uri?(key_id)
|
||||
account = ActivityPub::TagManager.instance.uri_to_resource(key_id, Account)
|
||||
account ||= ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false)
|
||||
account ||= ActivityPub::FetchRemoteKeyService.new.call(key_id)
|
||||
account
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,14 +7,12 @@ module UserTrackingConcern
|
||||
UPDATE_SIGN_IN_HOURS = 24
|
||||
|
||||
included do
|
||||
before_action :set_user_activity
|
||||
before_action :set_user_activity, if: %i(user_signed_in? user_needs_sign_in_update?)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user_activity
|
||||
return unless user_needs_sign_in_update?
|
||||
|
||||
# Mark as signed-in today
|
||||
current_user.update_tracked_fields!(request)
|
||||
|
||||
@@ -23,7 +21,7 @@ module UserTrackingConcern
|
||||
end
|
||||
|
||||
def user_needs_sign_in_update?
|
||||
user_signed_in? && (current_user.current_sign_in_at.nil? || current_user.current_sign_in_at < UPDATE_SIGN_IN_HOURS.hours.ago)
|
||||
current_user.current_sign_in_at.nil? || current_user.current_sign_in_at < UPDATE_SIGN_IN_HOURS.hours.ago
|
||||
end
|
||||
|
||||
def user_needs_feed_update?
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class EmojisController < ApplicationController
|
||||
before_action :set_emoji
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: @emoji,
|
||||
serializer: ActivityPub::EmojiSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_emoji
|
||||
@emoji = CustomEmoji.local.find(params[:id])
|
||||
end
|
||||
end
|
||||
@@ -7,44 +7,22 @@ class FollowerAccountsController < ApplicationController
|
||||
@follows = Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account)
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
end
|
||||
format.html
|
||||
|
||||
format.json do
|
||||
render json: collection_presenter,
|
||||
serializer: ActivityPub::CollectionSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def page_url(page)
|
||||
account_followers_url(@account, page: page) unless page.nil?
|
||||
end
|
||||
|
||||
def collection_presenter
|
||||
page = ActivityPub::CollectionPresenter.new(
|
||||
id: account_followers_url(@account, page: params.fetch(:page, 1)),
|
||||
type: :ordered,
|
||||
size: @account.followers_count,
|
||||
items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.account) },
|
||||
part_of: account_followers_url(@account),
|
||||
next: page_url(@follows.next_page),
|
||||
prev: page_url(@follows.prev_page)
|
||||
)
|
||||
if params[:page].present?
|
||||
page
|
||||
else
|
||||
ActivityPub::CollectionPresenter.new(
|
||||
id: account_followers_url(@account),
|
||||
type: :ordered,
|
||||
size: @account.followers_count,
|
||||
first: page
|
||||
items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.account) }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,44 +7,22 @@ class FollowingAccountsController < ApplicationController
|
||||
@follows = Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account)
|
||||
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
use_pack 'public'
|
||||
end
|
||||
format.html
|
||||
|
||||
format.json do
|
||||
render json: collection_presenter,
|
||||
serializer: ActivityPub::CollectionSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
render json: collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def page_url(page)
|
||||
account_following_index_url(@account, page: page) unless page.nil?
|
||||
end
|
||||
|
||||
def collection_presenter
|
||||
page = ActivityPub::CollectionPresenter.new(
|
||||
id: account_following_index_url(@account, page: params.fetch(:page, 1)),
|
||||
type: :ordered,
|
||||
size: @account.following_count,
|
||||
items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.target_account) },
|
||||
part_of: account_following_index_url(@account),
|
||||
next: page_url(@follows.next_page),
|
||||
prev: page_url(@follows.prev_page)
|
||||
)
|
||||
if params[:page].present?
|
||||
page
|
||||
else
|
||||
ActivityPub::CollectionPresenter.new(
|
||||
id: account_following_index_url(@account),
|
||||
type: :ordered,
|
||||
size: @account.following_count,
|
||||
first: page
|
||||
items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.target_account) }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
class HomeController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
before_action :set_initial_state_json
|
||||
|
||||
def index
|
||||
@@ -12,34 +11,7 @@ class HomeController < ApplicationController
|
||||
private
|
||||
|
||||
def authenticate_user!
|
||||
return if user_signed_in?
|
||||
|
||||
matches = request.path.match(/\A\/web\/(statuses|accounts)\/([\d]+)\z/)
|
||||
|
||||
if matches
|
||||
case matches[1]
|
||||
when 'statuses'
|
||||
status = Status.find_by(id: matches[2])
|
||||
|
||||
if status && (status.public_visibility? || status.unlisted_visibility?)
|
||||
redirect_to(ActivityPub::TagManager.instance.url_for(status))
|
||||
return
|
||||
end
|
||||
when 'accounts'
|
||||
account = Account.find_by(id: matches[2])
|
||||
|
||||
if account
|
||||
redirect_to(ActivityPub::TagManager.instance.url_for(account))
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to(default_redirect_path)
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'home'
|
||||
redirect_to(single_user_mode? ? account_path(Account.first) : about_path) unless user_signed_in?
|
||||
end
|
||||
|
||||
def set_initial_state_json
|
||||
@@ -56,14 +28,4 @@ class HomeController < ApplicationController
|
||||
admin: Account.find_local(Setting.site_contact_username),
|
||||
}
|
||||
end
|
||||
|
||||
def default_redirect_path
|
||||
if request.path.start_with?('/web')
|
||||
new_user_session_path
|
||||
elsif single_user_mode?
|
||||
short_account_path(Account.first)
|
||||
else
|
||||
about_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class InvitesController < ApplicationController
|
||||
include Authorization
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
|
||||
def index
|
||||
authorize :invite, :create?
|
||||
|
||||
@invites = Invite.where(user: current_user)
|
||||
@invite = Invite.new(expires_in: 1.day.to_i)
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :invite, :create?
|
||||
|
||||
@invite = Invite.new(resource_params)
|
||||
@invite.user = current_user
|
||||
|
||||
if @invite.save
|
||||
redirect_to invites_path
|
||||
else
|
||||
@invites = Invite.where(user: current_user)
|
||||
render :index
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@invite = Invite.where(user: current_user).find(params[:id])
|
||||
authorize @invite, :destroy?
|
||||
@invite.expire!
|
||||
redirect_to invites_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_pack
|
||||
use_pack 'settings'
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:invite).permit(:max_uses, :expires_in)
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ManifestsController < ApplicationController
|
||||
def show
|
||||
render json: InstancePresenter.new, serializer: ManifestSerializer
|
||||
before_action :set_instance_presenter
|
||||
|
||||
def show; end
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class MediaProxyController < ApplicationController
|
||||
include RoutingHelper
|
||||
|
||||
def show
|
||||
RedisLock.acquire(lock_options) do |lock|
|
||||
if lock.acquired?
|
||||
@media_attachment = MediaAttachment.remote.find(params[:id])
|
||||
redownload! if @media_attachment.needs_redownload? && !reject_media?
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to full_asset_url(@media_attachment.file.url(version))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redownload!
|
||||
@media_attachment.file_remote_url = @media_attachment.remote_url
|
||||
@media_attachment.created_at = Time.now.utc
|
||||
@media_attachment.save!
|
||||
end
|
||||
|
||||
def version
|
||||
if request.path.ends_with?('/small')
|
||||
:small
|
||||
else
|
||||
:original
|
||||
end
|
||||
end
|
||||
|
||||
def lock_options
|
||||
{ redis: Redis.current, key: "media_download:#{params[:id]}" }
|
||||
end
|
||||
|
||||
def reject_media?
|
||||
DomainBlock.find_by(domain: @media_attachment.account.domain)&.reject_media?
|
||||
end
|
||||
end
|
||||
@@ -5,7 +5,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||
|
||||
before_action :store_current_location
|
||||
before_action :authenticate_resource_owner!
|
||||
before_action :set_pack
|
||||
|
||||
include Localized
|
||||
|
||||
@@ -14,8 +13,4 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||
def store_current_location
|
||||
store_location_for(:user, request.url)
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'auth'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,6 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
||||
|
||||
before_action :store_current_location
|
||||
before_action :authenticate_resource_owner!
|
||||
before_action :set_pack
|
||||
|
||||
include Localized
|
||||
|
||||
@@ -14,8 +13,4 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
||||
def store_current_location
|
||||
store_location_for(:user, request.url)
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'settings'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,6 @@ class RemoteFollowController < ApplicationController
|
||||
layout 'modal'
|
||||
|
||||
before_action :set_account
|
||||
before_action :set_pack
|
||||
before_action :gone, if: :suspended_account?
|
||||
|
||||
def new
|
||||
@@ -32,10 +31,6 @@ class RemoteFollowController < ApplicationController
|
||||
{ acct: session[:remote_follow] }
|
||||
end
|
||||
|
||||
def set_pack
|
||||
use_pack 'modal'
|
||||
end
|
||||
|
||||
def set_account
|
||||
@account = Account.find_local!(params[:account_username])
|
||||
end
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ApplicationsController < Settings::BaseController
|
||||
class Settings::ApplicationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_application, only: [:show, :update, :destroy, :regenerate]
|
||||
before_action :prepare_scopes, only: [:create, :update]
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::BaseController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_pack
|
||||
|
||||
def set_pack
|
||||
use_pack 'settings'
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::DeletesController < Settings::BaseController
|
||||
class Settings::DeletesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
prepend_before_action :check_enabled_deletion
|
||||
before_action :check_enabled_deletion
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@confirmation = Form::DeleteConfirmation.new
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ExportsController < Settings::BaseController
|
||||
class Settings::ExportsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@export = Export.new(current_account)
|
||||
end
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::FlavoursController < Settings::BaseController
|
||||
|
||||
def index
|
||||
redirect_to action: 'show', flavour: current_flavour
|
||||
end
|
||||
|
||||
def show
|
||||
unless Themes.instance.flavours.include?(params[:flavour]) or params[:flavour] == current_flavour
|
||||
redirect_to action: 'show', flavour: current_flavour
|
||||
end
|
||||
|
||||
@listing = Themes.instance.flavours
|
||||
@selected = params[:flavour]
|
||||
end
|
||||
|
||||
def update
|
||||
user_settings.update(user_settings_params(params[:flavour]).to_h)
|
||||
redirect_to action: 'show', flavour: params[:flavour]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_settings
|
||||
UserSettingsDecorator.new(current_user)
|
||||
end
|
||||
|
||||
def user_settings_params(flavour)
|
||||
params.require(:user).merge({ setting_flavour: flavour }).permit(
|
||||
:setting_flavour,
|
||||
:setting_skin
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -2,10 +2,14 @@
|
||||
|
||||
require 'sidekiq-bulk'
|
||||
|
||||
class Settings::FollowerDomainsController < Settings::BaseController
|
||||
class Settings::FollowerDomainsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@account = current_account
|
||||
@domains = current_account.followers.reorder('MIN(follows.id) DESC').group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10)
|
||||
@domains = current_account.followers.reorder(nil).group('accounts.domain').select('accounts.domain, count(accounts.id) as accounts_from_domain').page(params[:page]).per(10)
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ImportsController < Settings::BaseController
|
||||
class Settings::ImportsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_account
|
||||
|
||||
def show
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::KeywordMutesController < Settings::BaseController
|
||||
before_action :load_keyword_mute, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@keyword_mutes = paginated_keyword_mutes_for_account
|
||||
end
|
||||
|
||||
def new
|
||||
@keyword_mute = keyword_mutes_for_account.build
|
||||
end
|
||||
|
||||
def create
|
||||
@keyword_mute = keyword_mutes_for_account.create(keyword_mute_params)
|
||||
|
||||
if @keyword_mute.persisted?
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @keyword_mute.update(keyword_mute_params)
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@keyword_mute.destroy!
|
||||
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
end
|
||||
|
||||
def destroy_all
|
||||
keyword_mutes_for_account.delete_all
|
||||
|
||||
redirect_to settings_keyword_mutes_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def keyword_mutes_for_account
|
||||
Glitch::KeywordMute.where(account: current_account)
|
||||
end
|
||||
|
||||
def load_keyword_mute
|
||||
@keyword_mute = keyword_mutes_for_account.find(params[:id])
|
||||
end
|
||||
|
||||
def keyword_mute_params
|
||||
params.require(:keyword_mute).permit(:keyword, :whole_word)
|
||||
end
|
||||
|
||||
def paginated_keyword_mutes_for_account
|
||||
keyword_mutes_for_account.order(:keyword).page params[:page]
|
||||
end
|
||||
end
|
||||
@@ -1,34 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::MigrationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
@migration = Form::Migration.new(account: current_account.moved_to_account)
|
||||
end
|
||||
|
||||
def update
|
||||
@migration = Form::Migration.new(resource_params)
|
||||
|
||||
if @migration.valid? && migration_account_changed?
|
||||
current_account.update!(moved_to_account: @migration.account)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
|
||||
redirect_to settings_migration_path, notice: I18n.t('migrations.updated_msg')
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.require(:migration).permit(:acct)
|
||||
end
|
||||
|
||||
def migration_account_changed?
|
||||
current_account.moved_to_account_id != @migration.account&.id &&
|
||||
current_account.id != @migration.account&.id
|
||||
end
|
||||
end
|
||||
@@ -1,28 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::NotificationsController < Settings::BaseController
|
||||
def show; end
|
||||
|
||||
def update
|
||||
user_settings.update(user_settings_params.to_h)
|
||||
|
||||
if current_user.save
|
||||
redirect_to settings_notifications_path, notice: I18n.t('generic.changes_saved_msg')
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_settings
|
||||
UserSettingsDecorator.new(current_user)
|
||||
end
|
||||
|
||||
def user_settings_params
|
||||
params.require(:user).permit(
|
||||
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
||||
interactions: %i(must_be_follower must_be_following must_be_following_dm)
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::PreferencesController < Settings::BaseController
|
||||
class Settings::PreferencesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show; end
|
||||
|
||||
def update
|
||||
@@ -33,10 +37,8 @@ class Settings::PreferencesController < Settings::BaseController
|
||||
:setting_default_sensitive,
|
||||
:setting_unfollow_modal,
|
||||
:setting_boost_modal,
|
||||
:setting_favourite_modal,
|
||||
:setting_delete_modal,
|
||||
:setting_auto_play_gif,
|
||||
:setting_reduce_motion,
|
||||
:setting_system_font_ui,
|
||||
:setting_noindex,
|
||||
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Settings::ProfilesController < Settings::BaseController
|
||||
class Settings::ProfilesController < ApplicationController
|
||||
include ObfuscateFilename
|
||||
|
||||
layout 'admin'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_account
|
||||
|
||||
obfuscate_filename [:account, :avatar]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Intentionally does not inherit from BaseController
|
||||
class Settings::SessionsController < ApplicationController
|
||||
before_action :set_session, only: :destroy
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user