mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 00:08:46 +00:00
Compare commits
3 Commits
450-make-n
...
feature/ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8375ed1cfd | ||
|
|
3d80ba01d7 | ||
|
|
f02150468b |
1
.babelrc
1
.babelrc
@@ -4,7 +4,6 @@
|
|||||||
[
|
[
|
||||||
"env",
|
"env",
|
||||||
{
|
{
|
||||||
"exclude": ["transform-async-to-generator", "transform-regenerator"],
|
|
||||||
"loose": true,
|
"loose": true,
|
||||||
"modules": false,
|
"modules": false,
|
||||||
"targets": {
|
"targets": {
|
||||||
|
|||||||
@@ -1,37 +1,21 @@
|
|||||||
version: "2"
|
engines:
|
||||||
checks:
|
|
||||||
argument-count:
|
|
||||||
enabled: false
|
|
||||||
complex-logic:
|
|
||||||
enabled: false
|
|
||||||
file-lines:
|
|
||||||
enabled: false
|
|
||||||
method-complexity:
|
|
||||||
enabled: false
|
|
||||||
method-count:
|
|
||||||
enabled: false
|
|
||||||
method-lines:
|
|
||||||
enabled: false
|
|
||||||
nested-control-flow:
|
|
||||||
enabled: false
|
|
||||||
return-statements:
|
|
||||||
enabled: false
|
|
||||||
similar-code:
|
|
||||||
enabled: false
|
|
||||||
identical-code:
|
|
||||||
enabled: false
|
|
||||||
plugins:
|
|
||||||
brakeman:
|
brakeman:
|
||||||
enabled: true
|
enabled: true
|
||||||
bundler-audit:
|
bundler-audit:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
duplication:
|
||||||
|
enabled: false
|
||||||
eslint:
|
eslint:
|
||||||
enabled: true
|
enabled: true
|
||||||
channel: eslint-4
|
|
||||||
rubocop:
|
rubocop:
|
||||||
enabled: true
|
enabled: true
|
||||||
scss-lint:
|
scss-lint:
|
||||||
enabled: true
|
enabled: true
|
||||||
exclude_patterns:
|
ratings:
|
||||||
|
paths:
|
||||||
|
- "**.rb"
|
||||||
|
- "**.js"
|
||||||
|
- "**.scss"
|
||||||
|
exclude_paths:
|
||||||
- spec/
|
- spec/
|
||||||
- vendor/asset
|
- vendor/asset
|
||||||
|
|||||||
@@ -11,4 +11,3 @@ vendor/bundle
|
|||||||
*~
|
*~
|
||||||
postgres
|
postgres
|
||||||
redis
|
redis
|
||||||
elasticsearch
|
|
||||||
|
|||||||
125
.env.nanobox
125
.env.nanobox
@@ -13,29 +13,11 @@ DB_PORT=5432
|
|||||||
|
|
||||||
DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano
|
DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano
|
||||||
|
|
||||||
# Optional ElasticSearch configuration
|
|
||||||
ES_ENABLED=true
|
|
||||||
ES_HOST=$DATA_ELASTIC_HOST
|
|
||||||
ES_PORT=9200
|
|
||||||
|
|
||||||
# Optimizations
|
|
||||||
LD_PRELOAD=/data/lib/libjemalloc.so
|
|
||||||
|
|
||||||
# ImageMagick optimizations
|
|
||||||
MAGICK_TEMPORARY_PATH=/app/tmp
|
|
||||||
MAGICK_MEMORY_LIMIT=128MiB
|
|
||||||
MAGICK_MAP_LIMIT=64MiB
|
|
||||||
MAGICK_TIME_LIMIT=15
|
|
||||||
MAGICK_AREA_LIMIT=16MP
|
|
||||||
MAGICK_WIDTH_LIMIT=8KP
|
|
||||||
MAGICK_HEIGHT_LIMIT=8KP
|
|
||||||
|
|
||||||
# Federation
|
# Federation
|
||||||
# Note: Changing LOCAL_DOMAIN at a later time will cause unwanted side effects, including breaking all existing federation.
|
# Note: Changing LOCAL_DOMAIN or LOCAL_HTTPS at a later time will cause unwanted side effects.
|
||||||
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
||||||
LOCAL_DOMAIN=${APP_NAME}.nanoapp.io
|
LOCAL_DOMAIN=${APP_NAME}.nanoapp.io
|
||||||
|
LOCAL_HTTPS=false
|
||||||
# Changing LOCAL_HTTPS in production is no longer supported. (Mastodon will always serve https:// links)
|
|
||||||
|
|
||||||
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
||||||
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
||||||
@@ -49,20 +31,10 @@ LOCAL_DOMAIN=${APP_NAME}.nanoapp.io
|
|||||||
|
|
||||||
# Application secrets
|
# Application secrets
|
||||||
# Generate each with the `rake secret` task (`nanobox run bundle exec rake secret`)
|
# Generate each with the `rake secret` task (`nanobox run bundle exec rake secret`)
|
||||||
|
PAPERCLIP_SECRET=$PAPERCLIP_SECRET
|
||||||
SECRET_KEY_BASE=$SECRET_KEY_BASE
|
SECRET_KEY_BASE=$SECRET_KEY_BASE
|
||||||
OTP_SECRET=$OTP_SECRET
|
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
|
# Registrations
|
||||||
# Single user mode will disable registrations and redirect frontpage to the first profile
|
# Single user mode will disable registrations and redirect frontpage to the first profile
|
||||||
# SINGLE_USER_MODE=true
|
# SINGLE_USER_MODE=true
|
||||||
@@ -90,7 +62,7 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
|||||||
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
|
#SMTP_CA_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||||
#SMTP_OPENSSL_VERIFY_MODE=peer
|
#SMTP_OPENSSL_VERIFY_MODE=peer
|
||||||
#SMTP_ENABLE_STARTTLS_AUTO=true
|
#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.
|
# Optional user upload path and URL (images, avatars). Default is :rails_root/public/system. If you set this variable, you are responsible for making your HTTP server (eg. nginx) serve these files.
|
||||||
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
# PAPERCLIP_ROOT_PATH=/var/lib/mastodon/public-system
|
||||||
@@ -119,23 +91,6 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
|||||||
# S3_ENDPOINT=
|
# S3_ENDPOINT=
|
||||||
# S3_SIGNATURE_VERSION=
|
# 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
|
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||||
# S3_CLOUDFRONT_HOST=
|
# S3_CLOUDFRONT_HOST=
|
||||||
|
|
||||||
@@ -148,79 +103,9 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
|||||||
|
|
||||||
# Cluster number setting for streaming API server.
|
# Cluster number setting for streaming API server.
|
||||||
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
|
# If you comment out following line, cluster number will be `numOfCpuCores - 1`.
|
||||||
# STREAMING_CLUSTER_NUM=1
|
STREAMING_CLUSTER_NUM=1
|
||||||
|
|
||||||
# Docker mastodon user
|
# Docker mastodon user
|
||||||
# If you use Docker, you may want to assign UID/GID manually.
|
# If you use Docker, you may want to assign UID/GID manually.
|
||||||
# UID=1000
|
# UID=1000
|
||||||
# GID=1000
|
# GID=1000
|
||||||
|
|
||||||
# LDAP authentication (optional)
|
|
||||||
# LDAP_ENABLED=true
|
|
||||||
# LDAP_HOST=localhost
|
|
||||||
# LDAP_PORT=389
|
|
||||||
# LDAP_METHOD=simple_tls
|
|
||||||
# LDAP_BASE=
|
|
||||||
# LDAP_BIND_DN=
|
|
||||||
# LDAP_PASSWORD=
|
|
||||||
# LDAP_UID=cn
|
|
||||||
|
|
||||||
# PAM authentication (optional)
|
|
||||||
# PAM authentication uses for the email generation the "email" pam variable
|
|
||||||
# and optional as fallback PAM_DEFAULT_SUFFIX
|
|
||||||
# The pam environment variable "email" is provided by:
|
|
||||||
# https://github.com/devkral/pam_email_extractor
|
|
||||||
# PAM_ENABLED=true
|
|
||||||
# Fallback Suffix for email address generation (nil by default)
|
|
||||||
# PAM_DEFAULT_SUFFIX=pam
|
|
||||||
# Name of the pam service (pam "auth" section is evaluated)
|
|
||||||
# PAM_DEFAULT_SERVICE=rpam
|
|
||||||
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
|
|
||||||
# PAM_CONTROLLED_SERVICE=rpam
|
|
||||||
|
|
||||||
# Global OAuth settings (optional) :
|
|
||||||
# If you have only one strategy, you may want to enable this
|
|
||||||
# OAUTH_REDIRECT_AT_SIGN_IN=true
|
|
||||||
|
|
||||||
# Optional CAS authentication (cf. omniauth-cas) :
|
|
||||||
# CAS_ENABLED=true
|
|
||||||
# CAS_URL=https://sso.myserver.com/
|
|
||||||
# CAS_HOST=sso.myserver.com/
|
|
||||||
# CAS_PORT=443
|
|
||||||
# CAS_SSL=true
|
|
||||||
# CAS_VALIDATE_URL=
|
|
||||||
# CAS_CALLBACK_URL=
|
|
||||||
# CAS_LOGOUT_URL=
|
|
||||||
# CAS_LOGIN_URL=
|
|
||||||
# CAS_UID_FIELD='user'
|
|
||||||
# CAS_CA_PATH=
|
|
||||||
# CAS_DISABLE_SSL_VERIFICATION=false
|
|
||||||
# CAS_UID_KEY='user'
|
|
||||||
# CAS_NAME_KEY='name'
|
|
||||||
# CAS_EMAIL_KEY='email'
|
|
||||||
# CAS_NICKNAME_KEY='nickname'
|
|
||||||
# CAS_FIRST_NAME_KEY='firstname'
|
|
||||||
# CAS_LAST_NAME_KEY='lastname'
|
|
||||||
# CAS_LOCATION_KEY='location'
|
|
||||||
# CAS_IMAGE_KEY='image'
|
|
||||||
# CAS_PHONE_KEY='phone'
|
|
||||||
|
|
||||||
# Optional SAML authentication (cf. omniauth-saml)
|
|
||||||
# SAML_ENABLED=true
|
|
||||||
# SAML_ACS_URL=
|
|
||||||
# SAML_ISSUER=http://localhost:3000/auth/auth/saml/callback
|
|
||||||
# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO
|
|
||||||
# SAML_IDP_CERT=
|
|
||||||
# SAML_IDP_CERT_FINGERPRINT=
|
|
||||||
# SAML_NAME_IDENTIFIER_FORMAT=
|
|
||||||
# SAML_CERT=
|
|
||||||
# SAML_PRIVATE_KEY=
|
|
||||||
# SAML_SECURITY_WANT_ASSERTION_SIGNED=true
|
|
||||||
# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true
|
|
||||||
# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.5.4.42"
|
|
||||||
# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED=
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL=
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Service dependencies
|
# Service dependencies
|
||||||
# You may set REDIS_URL instead for more advanced options
|
# 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_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
# You may set DATABASE_URL instead for more advanced options
|
# You may set DATABASE_URL instead for more advanced options
|
||||||
@@ -9,17 +8,12 @@ DB_USER=postgres
|
|||||||
DB_NAME=postgres
|
DB_NAME=postgres
|
||||||
DB_PASS=
|
DB_PASS=
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
# Optional ElasticSearch configuration
|
|
||||||
# ES_ENABLED=true
|
|
||||||
# ES_HOST=es
|
|
||||||
# ES_PORT=9200
|
|
||||||
|
|
||||||
# Federation
|
# Federation
|
||||||
# Note: Changing LOCAL_DOMAIN at a later time will cause unwanted side effects, including breaking all existing federation.
|
# Note: Changing LOCAL_DOMAIN or LOCAL_HTTPS at a later time will cause unwanted side effects.
|
||||||
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
||||||
LOCAL_DOMAIN=example.com
|
LOCAL_DOMAIN=example.com
|
||||||
|
LOCAL_HTTPS=true
|
||||||
# Changing LOCAL_HTTPS in production is no longer supported. (Mastodon will always serve https:// links)
|
|
||||||
|
|
||||||
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
||||||
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
||||||
@@ -33,6 +27,7 @@ LOCAL_DOMAIN=example.com
|
|||||||
|
|
||||||
# Application secrets
|
# 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 `RAILS_ENV=production bundle exec rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
|
||||||
|
PAPERCLIP_SECRET=
|
||||||
SECRET_KEY_BASE=
|
SECRET_KEY_BASE=
|
||||||
OTP_SECRET=
|
OTP_SECRET=
|
||||||
|
|
||||||
@@ -81,10 +76,6 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
|||||||
# PAPERCLIP_ROOT_URL=/system
|
# PAPERCLIP_ROOT_URL=/system
|
||||||
|
|
||||||
# Optional asset host for multi-server setups
|
# Optional asset host for multi-server setups
|
||||||
# The asset host must allow cross origin request from WEB_DOMAIN or LOCAL_DOMAIN
|
|
||||||
# if WEB_DOMAIN is not set. For example, the server may have the
|
|
||||||
# following header field:
|
|
||||||
# Access-Control-Allow-Origin: https://example.com/
|
|
||||||
# CDN_HOST=https://assets.example.com
|
# CDN_HOST=https://assets.example.com
|
||||||
|
|
||||||
# S3 (optional)
|
# S3 (optional)
|
||||||
@@ -110,19 +101,11 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
|||||||
# Swift (optional)
|
# Swift (optional)
|
||||||
# SWIFT_ENABLED=true
|
# SWIFT_ENABLED=true
|
||||||
# SWIFT_USERNAME=
|
# SWIFT_USERNAME=
|
||||||
# For Keystone V3, the value for SWIFT_TENANT should be the project name
|
|
||||||
# SWIFT_TENANT=
|
# SWIFT_TENANT=
|
||||||
# SWIFT_PASSWORD=
|
# 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_AUTH_URL=
|
||||||
# SWIFT_CONTAINER=
|
# SWIFT_CONTAINER=
|
||||||
# SWIFT_OBJECT_URL=
|
# 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
|
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||||
# S3_CLOUDFRONT_HOST=
|
# S3_CLOUDFRONT_HOST=
|
||||||
@@ -142,78 +125,3 @@ STREAMING_CLUSTER_NUM=1
|
|||||||
# If you use Docker, you may want to assign UID/GID manually.
|
# If you use Docker, you may want to assign UID/GID manually.
|
||||||
# UID=1000
|
# UID=1000
|
||||||
# GID=1000
|
# GID=1000
|
||||||
|
|
||||||
# Maximum allowed character count
|
|
||||||
# MAX_TOOT_CHARS=500
|
|
||||||
|
|
||||||
# LDAP authentication (optional)
|
|
||||||
# LDAP_ENABLED=true
|
|
||||||
# LDAP_HOST=localhost
|
|
||||||
# LDAP_PORT=389
|
|
||||||
# LDAP_METHOD=simple_tls
|
|
||||||
# LDAP_BASE=
|
|
||||||
# LDAP_BIND_DN=
|
|
||||||
# LDAP_PASSWORD=
|
|
||||||
# LDAP_UID=cn
|
|
||||||
|
|
||||||
# PAM authentication (optional)
|
|
||||||
# PAM authentication uses for the email generation the "email" pam variable
|
|
||||||
# and optional as fallback PAM_DEFAULT_SUFFIX
|
|
||||||
# The pam environment variable "email" is provided by:
|
|
||||||
# https://github.com/devkral/pam_email_extractor
|
|
||||||
# PAM_ENABLED=true
|
|
||||||
# Fallback email domain for email address generation (LOCAL_DOMAIN by default)
|
|
||||||
# PAM_EMAIL_DOMAIN=example.com
|
|
||||||
# Name of the pam service (pam "auth" section is evaluated)
|
|
||||||
# PAM_DEFAULT_SERVICE=rpam
|
|
||||||
# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default)
|
|
||||||
# PAM_CONTROLLED_SERVICE=rpam
|
|
||||||
|
|
||||||
# Global OAuth settings (optional) :
|
|
||||||
# If you have only one strategy, you may want to enable this
|
|
||||||
# OAUTH_REDIRECT_AT_SIGN_IN=true
|
|
||||||
|
|
||||||
# Optional CAS authentication (cf. omniauth-cas) :
|
|
||||||
# CAS_ENABLED=true
|
|
||||||
# CAS_URL=https://sso.myserver.com/
|
|
||||||
# CAS_HOST=sso.myserver.com/
|
|
||||||
# CAS_PORT=443
|
|
||||||
# CAS_SSL=true
|
|
||||||
# CAS_VALIDATE_URL=
|
|
||||||
# CAS_CALLBACK_URL=
|
|
||||||
# CAS_LOGOUT_URL=
|
|
||||||
# CAS_LOGIN_URL=
|
|
||||||
# CAS_UID_FIELD='user'
|
|
||||||
# CAS_CA_PATH=
|
|
||||||
# CAS_DISABLE_SSL_VERIFICATION=false
|
|
||||||
# CAS_UID_KEY='user'
|
|
||||||
# CAS_NAME_KEY='name'
|
|
||||||
# CAS_EMAIL_KEY='email'
|
|
||||||
# CAS_NICKNAME_KEY='nickname'
|
|
||||||
# CAS_FIRST_NAME_KEY='firstname'
|
|
||||||
# CAS_LAST_NAME_KEY='lastname'
|
|
||||||
# CAS_LOCATION_KEY='location'
|
|
||||||
# CAS_IMAGE_KEY='image'
|
|
||||||
# CAS_PHONE_KEY='phone'
|
|
||||||
|
|
||||||
# Optional SAML authentication (cf. omniauth-saml)
|
|
||||||
# SAML_ENABLED=true
|
|
||||||
# SAML_ACS_URL=
|
|
||||||
# SAML_ISSUER=http://localhost:3000/auth/auth/saml/callback
|
|
||||||
# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO
|
|
||||||
# SAML_IDP_CERT=
|
|
||||||
# SAML_IDP_CERT_FINGERPRINT=
|
|
||||||
# SAML_NAME_IDENTIFIER_FORMAT=
|
|
||||||
# SAML_CERT=
|
|
||||||
# SAML_PRIVATE_KEY=
|
|
||||||
# SAML_SECURITY_WANT_ASSERTION_SIGNED=true
|
|
||||||
# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true
|
|
||||||
# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4"
|
|
||||||
# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1"
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED=
|
|
||||||
# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL=
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
# Federation
|
# Federation
|
||||||
LOCAL_DOMAIN=cb6e6126.ngrok.io
|
LOCAL_DOMAIN=cb6e6126.ngrok.io
|
||||||
LOCAL_HTTPS=true
|
LOCAL_HTTPS=true
|
||||||
# test pam authentication
|
OTP_SECRET=100c7faeef00caa29242f6b04156742bf76065771fd4117990c4282b8748ff3d99f8fdae97c982ab5bd2e6756a159121377cce4421f4a8ecd2d67bd7749a3fb4
|
||||||
PAM_ENABLED=true
|
|
||||||
PAM_DEFAULT_SERVICE=pam_test
|
|
||||||
PAM_CONTROLLED_SERVICE=pam_test_controlled
|
|
||||||
|
|||||||
@@ -5,36 +5,24 @@ env:
|
|||||||
browser: true
|
browser: true
|
||||||
node: true
|
node: true
|
||||||
es6: true
|
es6: true
|
||||||
jest: true
|
|
||||||
|
|
||||||
parser: babel-eslint
|
parser: babel-eslint
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- react
|
- react
|
||||||
- jsx-a11y
|
- jsx-a11y
|
||||||
- import
|
|
||||||
- promise
|
|
||||||
|
|
||||||
parserOptions:
|
parserOptions:
|
||||||
sourceType: module
|
sourceType: module
|
||||||
ecmaFeatures:
|
ecmaFeatures:
|
||||||
experimentalObjectRestSpread: true
|
arrowFunctions: true
|
||||||
jsx: true
|
jsx: true
|
||||||
ecmaVersion: 2018
|
destructuring: true
|
||||||
|
modules: true
|
||||||
settings:
|
spread: true
|
||||||
import/extensions:
|
|
||||||
- .js
|
|
||||||
import/ignore:
|
|
||||||
- node_modules
|
|
||||||
- \\.(css|scss|json)$
|
|
||||||
import/resolver:
|
|
||||||
node:
|
|
||||||
moduleDirectory:
|
|
||||||
- node_modules
|
|
||||||
- app/javascript
|
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
|
|
||||||
brace-style: warn
|
brace-style: warn
|
||||||
comma-dangle:
|
comma-dangle:
|
||||||
- error
|
- error
|
||||||
@@ -113,7 +101,6 @@ rules:
|
|||||||
react/self-closing-comp: error
|
react/self-closing-comp: error
|
||||||
|
|
||||||
jsx-a11y/accessible-emoji: warn
|
jsx-a11y/accessible-emoji: warn
|
||||||
jsx-a11y/alt-text: warn
|
|
||||||
jsx-a11y/anchor-has-content: warn
|
jsx-a11y/anchor-has-content: warn
|
||||||
jsx-a11y/aria-activedescendant-has-tabindex: warn
|
jsx-a11y/aria-activedescendant-has-tabindex: warn
|
||||||
jsx-a11y/aria-props: warn
|
jsx-a11y/aria-props: warn
|
||||||
@@ -124,39 +111,17 @@ rules:
|
|||||||
jsx-a11y/href-no-hash: warn
|
jsx-a11y/href-no-hash: warn
|
||||||
jsx-a11y/html-has-lang: warn
|
jsx-a11y/html-has-lang: warn
|
||||||
jsx-a11y/iframe-has-title: warn
|
jsx-a11y/iframe-has-title: warn
|
||||||
|
jsx-a11y/img-has-alt: warn
|
||||||
jsx-a11y/img-redundant-alt: warn
|
jsx-a11y/img-redundant-alt: warn
|
||||||
jsx-a11y/interactive-supports-focus: warn
|
|
||||||
jsx-a11y/label-has-for: off
|
jsx-a11y/label-has-for: off
|
||||||
jsx-a11y/mouse-events-have-key-events: warn
|
jsx-a11y/mouse-events-have-key-events: warn
|
||||||
jsx-a11y/no-access-key: warn
|
jsx-a11y/no-access-key: warn
|
||||||
jsx-a11y/no-distracting-elements: warn
|
jsx-a11y/no-distracting-elements: warn
|
||||||
jsx-a11y/no-noninteractive-element-interactions:
|
|
||||||
- warn
|
|
||||||
- handlers:
|
|
||||||
- onClick
|
|
||||||
jsx-a11y/no-onchange: warn
|
jsx-a11y/no-onchange: warn
|
||||||
jsx-a11y/no-redundant-roles: warn
|
jsx-a11y/no-redundant-roles: warn
|
||||||
jsx-a11y/no-static-element-interactions:
|
jsx-a11y/onclick-has-focus: warn
|
||||||
- warn
|
jsx-a11y/onclick-has-role: warn
|
||||||
- handlers:
|
|
||||||
- onClick
|
|
||||||
jsx-a11y/role-has-required-aria-props: warn
|
jsx-a11y/role-has-required-aria-props: warn
|
||||||
jsx-a11y/role-supports-aria-props: off
|
jsx-a11y/role-supports-aria-props: off
|
||||||
jsx-a11y/scope: warn
|
jsx-a11y/scope: warn
|
||||||
jsx-a11y/tabindex-no-positive: 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
|
|
||||||
|
|
||||||
promise/catch-or-return: 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
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -36,10 +36,9 @@ config/deploy/*
|
|||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
# Ignore postgres + redis + elasticsearch volume optionally created by docker-compose
|
# Ignore postgres + redis volume optionally created by docker-compose
|
||||||
postgres
|
postgres
|
||||||
redis
|
redis
|
||||||
elasticsearch
|
|
||||||
|
|
||||||
# Ignore Apple files
|
# Ignore Apple files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
0
.gitmodules
vendored
0
.gitmodules
vendored
@@ -1 +1 @@
|
|||||||
2.5.1
|
2.4.1
|
||||||
|
|||||||
27
.travis.yml
27
.travis.yml
@@ -8,7 +8,7 @@ cache:
|
|||||||
- public/packs-test
|
- public/packs-test
|
||||||
- tmp/cache/babel-loader
|
- tmp/cache/babel-loader
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: false
|
sudo: required
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
@@ -18,39 +18,42 @@ env:
|
|||||||
- LOCAL_DOMAIN=cb6e6126.ngrok.io
|
- LOCAL_DOMAIN=cb6e6126.ngrok.io
|
||||||
- LOCAL_HTTPS=true
|
- LOCAL_HTTPS=true
|
||||||
- RAILS_ENV=test
|
- RAILS_ENV=test
|
||||||
|
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
||||||
- PARALLEL_TEST_PROCESSORS=2
|
- PARALLEL_TEST_PROCESSORS=2
|
||||||
- ALLOW_NOPAM=true
|
- "PATH=$HOME:$PATH"
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
postgresql: 9.4
|
postgresql: 9.4
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
|
- ubuntu-toolchain-r-test
|
||||||
- trusty-media
|
- trusty-media
|
||||||
- sourceline: deb https://dl.yarnpkg.com/debian/ stable main
|
|
||||||
key_url: https://dl.yarnpkg.com/debian/pubkey.gpg
|
|
||||||
packages:
|
packages:
|
||||||
- ffmpeg
|
- ffmpeg
|
||||||
- libicu-dev
|
- g++-6
|
||||||
- libprotobuf-dev
|
- libprotobuf-dev
|
||||||
- protobuf-compiler
|
- protobuf-compiler
|
||||||
- yarn
|
- libicu-dev
|
||||||
|
|
||||||
rvm:
|
rvm:
|
||||||
- 2.4.3
|
- 2.3.4
|
||||||
- 2.5.0
|
- 2.4.1
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- redis-server
|
- redis-server
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- nvm install
|
- nvm install
|
||||||
- bundle install --path=vendor/bundle --with pam_authentication --without development production --retry=3 --jobs=16
|
- npm install -g yarn
|
||||||
|
- bundle install --path=vendor/bundle --without development production --retry=3 --jobs=16
|
||||||
- yarn install
|
- yarn install
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- travis_wait ./bin/rails parallel:create parallel:load_schema parallel:prepare assets:precompile
|
- bundle exec rake parallel:create parallel:load_schema parallel:prepare
|
||||||
|
- bundle exec rails assets:precompile
|
||||||
|
- ln -s /usr/bin/x86_64-linux-gnu-g++-6 "$HOME/g++"
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
|
- travis_retry bundle exec parallel_test spec/ --group-by filesize --type rspec
|
||||||
- yarn run test:jest
|
- npm test
|
||||||
- bundle exec i18n-tasks check-normalized && bundle exec i18n-tasks unused
|
- 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
|
|
||||||
|
|
||||||
450
AUTHORS.md
450
AUTHORS.md
@@ -1,450 +0,0 @@
|
|||||||
Mastodon is available on [GitHub](https://github.com/tootsuite/mastodon)
|
|
||||||
and provided thanks to the work of the following contributors:
|
|
||||||
|
|
||||||
* [Gargron](https://github.com/Gargron)
|
|
||||||
* [ykzts](https://github.com/ykzts)
|
|
||||||
* [mjankowski](https://github.com/mjankowski)
|
|
||||||
* [akihikodaki](https://github.com/akihikodaki)
|
|
||||||
* [unarist](https://github.com/unarist)
|
|
||||||
* [yiskah](https://github.com/yiskah)
|
|
||||||
* [m4sk1n](https://github.com/m4sk1n)
|
|
||||||
* [nolanlawson](https://github.com/nolanlawson)
|
|
||||||
* [sorin-davidoi](https://github.com/sorin-davidoi)
|
|
||||||
* [abcang](https://github.com/abcang)
|
|
||||||
* [ThibG](https://github.com/ThibG)
|
|
||||||
* [lynlynlynx](https://github.com/lynlynlynx)
|
|
||||||
* [alpaca-tc](https://github.com/alpaca-tc)
|
|
||||||
* [nclm](https://github.com/nclm)
|
|
||||||
* [ineffyble](https://github.com/ineffyble)
|
|
||||||
* [jeroenpraat](https://github.com/jeroenpraat)
|
|
||||||
* [blackle](https://github.com/blackle)
|
|
||||||
* [Quent-in](https://github.com/Quent-in)
|
|
||||||
* [JantsoP](https://github.com/JantsoP)
|
|
||||||
* [nullkal](https://github.com/nullkal)
|
|
||||||
* [yookoala](https://github.com/yookoala)
|
|
||||||
* [ysksn](https://github.com/ysksn)
|
|
||||||
* [ashfurrow](https://github.com/ashfurrow)
|
|
||||||
* [eramdam](https://github.com/eramdam)
|
|
||||||
* [mayaeh](https://github.com/mayaeh)
|
|
||||||
* [zunda](https://github.com/zunda)
|
|
||||||
* [ticky](https://github.com/ticky)
|
|
||||||
* [masarakki](https://github.com/masarakki)
|
|
||||||
* [Wonderfall](https://github.com/Wonderfall)
|
|
||||||
* [matteoaquila](https://github.com/matteoaquila)
|
|
||||||
* [rkarabut](https://github.com/rkarabut)
|
|
||||||
* [stephenburgess8](https://github.com/stephenburgess8)
|
|
||||||
* [Kjwon15](https://github.com/Kjwon15)
|
|
||||||
* [Artoria2e5](https://github.com/Artoria2e5)
|
|
||||||
* [yukimochi](https://github.com/yukimochi)
|
|
||||||
* [marrus-sh](https://github.com/marrus-sh)
|
|
||||||
* [krainboltgreene](https://github.com/krainboltgreene)
|
|
||||||
* [renatolond](https://github.com/renatolond)
|
|
||||||
* [BoFFire](https://github.com/BoFFire)
|
|
||||||
* [clworld](https://github.com/clworld)
|
|
||||||
* [danhunsaker](https://github.com/danhunsaker)
|
|
||||||
* [patf](https://github.com/patf)
|
|
||||||
* [Quenty31](https://github.com/Quenty31)
|
|
||||||
* [MitarashiDango](https://github.com/MitarashiDango)
|
|
||||||
* [Aldarone](https://github.com/Aldarone)
|
|
||||||
* [JeanGauthier](https://github.com/JeanGauthier)
|
|
||||||
* [kschaper](https://github.com/kschaper)
|
|
||||||
* [takayamaki](https://github.com/takayamaki)
|
|
||||||
* [adbelle](https://github.com/adbelle)
|
|
||||||
* [evanminto](https://github.com/evanminto)
|
|
||||||
* [mabkenar](https://github.com/mabkenar)
|
|
||||||
* [MightyPork](https://github.com/MightyPork)
|
|
||||||
* [beatrix-bitrot](https://github.com/beatrix-bitrot)
|
|
||||||
* [yhirano55](https://github.com/yhirano55)
|
|
||||||
* [camponez](https://github.com/camponez)
|
|
||||||
* [aschmitz](https://github.com/aschmitz)
|
|
||||||
* [fpiesche](https://github.com/fpiesche)
|
|
||||||
* [gandaro](https://github.com/gandaro)
|
|
||||||
* [johnsudaar](https://github.com/johnsudaar)
|
|
||||||
* [trebmuh](https://github.com/trebmuh)
|
|
||||||
* [Sylvhem](https://github.com/Sylvhem)
|
|
||||||
* [lindwurm](https://github.com/lindwurm)
|
|
||||||
* [voidsatisfaction](https://github.com/voidsatisfaction)
|
|
||||||
* [neetshin](https://github.com/neetshin)
|
|
||||||
* [valentin2105](https://github.com/valentin2105)
|
|
||||||
* [hikari-no-yume](https://github.com/hikari-no-yume)
|
|
||||||
* [Angristan](https://github.com/Angristan)
|
|
||||||
* [seefood](https://github.com/seefood)
|
|
||||||
* [jackjennings](https://github.com/jackjennings)
|
|
||||||
* [hcmiya](https://github.com/hcmiya)
|
|
||||||
* [nightpool](https://github.com/nightpool)
|
|
||||||
* [salvadorpla](https://github.com/salvadorpla)
|
|
||||||
* [expenses](https://github.com/expenses)
|
|
||||||
* [walf443](https://github.com/walf443)
|
|
||||||
* [JoelQ](https://github.com/JoelQ)
|
|
||||||
* [mistydemeo](https://github.com/mistydemeo)
|
|
||||||
* [dunn](https://github.com/dunn)
|
|
||||||
* [xqus](https://github.com/xqus)
|
|
||||||
* [pfm-eyesightjp](https://github.com/pfm-eyesightjp)
|
|
||||||
* [fakenine](https://github.com/fakenine)
|
|
||||||
* [tsuwatch](https://github.com/tsuwatch)
|
|
||||||
* [victorhck](https://github.com/victorhck)
|
|
||||||
* [puckipedia](https://github.com/puckipedia)
|
|
||||||
* [contraexemplo](https://github.com/contraexemplo)
|
|
||||||
* [kazu9su](https://github.com/kazu9su)
|
|
||||||
* [Komic](https://github.com/Komic)
|
|
||||||
* [diomed](https://github.com/diomed)
|
|
||||||
* [rainyday](https://github.com/rainyday)
|
|
||||||
* [kadiix](https://github.com/kadiix)
|
|
||||||
* [kodacs](https://github.com/kodacs)
|
|
||||||
* [ProgVal](https://github.com/ProgVal)
|
|
||||||
* [sterdev](https://github.com/sterdev)
|
|
||||||
* [TheKinrar](https://github.com/TheKinrar)
|
|
||||||
* [AA4ch1](https://github.com/AA4ch1)
|
|
||||||
* [alexgleason](https://github.com/alexgleason)
|
|
||||||
* [cpytel](https://github.com/cpytel)
|
|
||||||
* [northerner](https://github.com/northerner)
|
|
||||||
* [hnrysmth](https://github.com/hnrysmth)
|
|
||||||
* [hugogameiro](https://github.com/hugogameiro)
|
|
||||||
* [JohnD28](https://github.com/JohnD28)
|
|
||||||
* [znz](https://github.com/znz)
|
|
||||||
* [Naouak](https://github.com/Naouak)
|
|
||||||
* [rtucker](https://github.com/rtucker)
|
|
||||||
* [reneklacan](https://github.com/reneklacan)
|
|
||||||
* [KScl](https://github.com/KScl)
|
|
||||||
* [SerCom-KC](https://github.com/SerCom-KC)
|
|
||||||
* [tcitworld](https://github.com/tcitworld)
|
|
||||||
* [geta6](https://github.com/geta6)
|
|
||||||
* [goofy-bz](https://github.com/goofy-bz)
|
|
||||||
* [happycoloredbanana](https://github.com/happycoloredbanana)
|
|
||||||
* [leopku](https://github.com/leopku)
|
|
||||||
* [SansPseudoFix](https://github.com/SansPseudoFix)
|
|
||||||
* [tomfhowe](https://github.com/tomfhowe)
|
|
||||||
* [noraworld](https://github.com/noraworld)
|
|
||||||
* [fvh-P](https://github.com/fvh-P)
|
|
||||||
* [178inaba](https://github.com/178inaba)
|
|
||||||
* [devkral](https://github.com/devkral)
|
|
||||||
* [alyssais](https://github.com/alyssais)
|
|
||||||
* [kodnaplakal](https://github.com/kodnaplakal)
|
|
||||||
* [stalker314314](https://github.com/stalker314314)
|
|
||||||
* [huertanix](https://github.com/huertanix)
|
|
||||||
* [genesixx](https://github.com/genesixx)
|
|
||||||
* [fhemberger](https://github.com/fhemberger)
|
|
||||||
* [halkeye](https://github.com/halkeye)
|
|
||||||
* [treby](https://github.com/treby)
|
|
||||||
* [d6rkaiz](https://github.com/d6rkaiz)
|
|
||||||
* [jpdevries](https://github.com/jpdevries)
|
|
||||||
* [rndm-stranger](https://github.com/rndm-stranger)
|
|
||||||
* [saper](https://github.com/saper)
|
|
||||||
* [nevillepark](https://github.com/nevillepark)
|
|
||||||
* [ornithocoder](https://github.com/ornithocoder)
|
|
||||||
* [pierreozoux](https://github.com/pierreozoux)
|
|
||||||
* [ramlmn](https://github.com/ramlmn)
|
|
||||||
* [harukasan](https://github.com/harukasan)
|
|
||||||
* [stamak](https://github.com/stamak)
|
|
||||||
* [Eychics](https://github.com/Eychics)
|
|
||||||
* [thor-the-norseman](https://github.com/thor-the-norseman)
|
|
||||||
* [0x70b1a5](https://github.com/0x70b1a5)
|
|
||||||
* [gled-rs](https://github.com/gled-rs)
|
|
||||||
* [R0ckweb](https://github.com/R0ckweb)
|
|
||||||
* [esetomo](https://github.com/esetomo)
|
|
||||||
* [foxiehkins](https://github.com/foxiehkins)
|
|
||||||
* [sdukhovni](https://github.com/sdukhovni)
|
|
||||||
* [unsmell](https://github.com/unsmell)
|
|
||||||
* [chriswmartin](https://github.com/chriswmartin)
|
|
||||||
* [vahnj](https://github.com/vahnj)
|
|
||||||
* [ikuradon](https://github.com/ikuradon)
|
|
||||||
* [AndreLewin](https://github.com/AndreLewin)
|
|
||||||
* [redtachyons](https://github.com/redtachyons)
|
|
||||||
* [thurloat](https://github.com/thurloat)
|
|
||||||
* [aaribaud](https://github.com/aaribaud)
|
|
||||||
* [estuans](https://github.com/estuans)
|
|
||||||
* [dissolve](https://github.com/dissolve)
|
|
||||||
* [PurpleBooth](https://github.com/PurpleBooth)
|
|
||||||
* [bradurani](https://github.com/bradurani)
|
|
||||||
* [wavebeem](https://github.com/wavebeem)
|
|
||||||
* [bruwalfas](https://github.com/bruwalfas)
|
|
||||||
* [foxsan48](https://github.com/foxsan48)
|
|
||||||
* [wchristian](https://github.com/wchristian)
|
|
||||||
* [muffinista](https://github.com/muffinista)
|
|
||||||
* [cdutson](https://github.com/cdutson)
|
|
||||||
* [farlistener](https://github.com/farlistener)
|
|
||||||
* [DavidLibeau](https://github.com/DavidLibeau)
|
|
||||||
* [SirCmpwn](https://github.com/SirCmpwn)
|
|
||||||
* [MasterGroosha](https://github.com/MasterGroosha)
|
|
||||||
* [Fjoerfoks](https://github.com/Fjoerfoks)
|
|
||||||
* [fmauNeko](https://github.com/fmauNeko)
|
|
||||||
* [gloaec](https://github.com/gloaec)
|
|
||||||
* [greysteil](https://github.com/greysteil)
|
|
||||||
* [unstabler](https://github.com/unstabler)
|
|
||||||
* [potato4d](https://github.com/potato4d)
|
|
||||||
* [h-izumi](https://github.com/h-izumi)
|
|
||||||
* [ErikXXon](https://github.com/ErikXXon)
|
|
||||||
* [ian-kelling](https://github.com/ian-kelling)
|
|
||||||
* [foozmeat](https://github.com/foozmeat)
|
|
||||||
* [jasonrhodes](https://github.com/jasonrhodes)
|
|
||||||
* [asm](https://github.com/asm)
|
|
||||||
* [jviide](https://github.com/jviide)
|
|
||||||
* [crakaC](https://github.com/crakaC)
|
|
||||||
* [tkbky](https://github.com/tkbky)
|
|
||||||
* [Kazhnuz](https://github.com/Kazhnuz)
|
|
||||||
* [alimony](https://github.com/alimony)
|
|
||||||
* [mig5](https://github.com/mig5)
|
|
||||||
* [ndarville](https://github.com/ndarville)
|
|
||||||
* [Abzol](https://github.com/Abzol)
|
|
||||||
* [xPaw](https://github.com/xPaw)
|
|
||||||
* [raymestalez](https://github.com/raymestalez)
|
|
||||||
* [sim6](https://github.com/sim6)
|
|
||||||
* [ekiru](https://github.com/ekiru)
|
|
||||||
* [Technowix](https://github.com/Technowix)
|
|
||||||
* [ThomasLeister](https://github.com/ThomasLeister)
|
|
||||||
* [mcat-ee](https://github.com/mcat-ee)
|
|
||||||
* [tototoshi](https://github.com/tototoshi)
|
|
||||||
* [VirtuBox](https://github.com/VirtuBox)
|
|
||||||
* [kaniini](https://github.com/kaniini)
|
|
||||||
* [vayan](https://github.com/vayan)
|
|
||||||
* [yannicka](https://github.com/yannicka)
|
|
||||||
* [ikasoumen](https://github.com/ikasoumen)
|
|
||||||
* [zacanger](https://github.com/zacanger)
|
|
||||||
* [amazedkoumei](https://github.com/amazedkoumei)
|
|
||||||
* [anon5r](https://github.com/anon5r)
|
|
||||||
* [codl](https://github.com/codl)
|
|
||||||
* [barzamin](https://github.com/barzamin)
|
|
||||||
* [fhalna](https://github.com/fhalna)
|
|
||||||
* [haoyayoi](https://github.com/haoyayoi)
|
|
||||||
* [ik11235](https://github.com/ik11235)
|
|
||||||
* [kawax](https://github.com/kawax)
|
|
||||||
* [007lva](https://github.com/007lva)
|
|
||||||
* [matsurai25](https://github.com/matsurai25)
|
|
||||||
* [mecab](https://github.com/mecab)
|
|
||||||
* [nicobz25](https://github.com/nicobz25)
|
|
||||||
* [oliverkeeble](https://github.com/oliverkeeble)
|
|
||||||
* [pinfort](https://github.com/pinfort)
|
|
||||||
* [rbaumert](https://github.com/rbaumert)
|
|
||||||
* [usagi-f](https://github.com/usagi-f)
|
|
||||||
* [vidarlee](https://github.com/vidarlee)
|
|
||||||
* [vjackson725](https://github.com/vjackson725)
|
|
||||||
* [wxcafe](https://github.com/wxcafe)
|
|
||||||
* [rinsuki](https://github.com/rinsuki)
|
|
||||||
* [cygnan](https://github.com/cygnan)
|
|
||||||
* [Awea](https://github.com/Awea)
|
|
||||||
* [halcy](https://github.com/halcy)
|
|
||||||
* [bounshi](https://github.com/bounshi)
|
|
||||||
* [8398a7](https://github.com/8398a7)
|
|
||||||
* [857b](https://github.com/857b)
|
|
||||||
* [unascribed](https://github.com/unascribed)
|
|
||||||
* [Aguay-val](https://github.com/Aguay-val)
|
|
||||||
* [knu](https://github.com/knu)
|
|
||||||
* [alxrcs](https://github.com/alxrcs)
|
|
||||||
* [console-cowboy](https://github.com/console-cowboy)
|
|
||||||
* [pointlessone](https://github.com/pointlessone)
|
|
||||||
* [a2](https://github.com/a2)
|
|
||||||
* [0xa](https://github.com/0xa)
|
|
||||||
* [virtualpain](https://github.com/virtualpain)
|
|
||||||
* [sapphirus](https://github.com/sapphirus)
|
|
||||||
* [amandavisconti](https://github.com/amandavisconti)
|
|
||||||
* [ameliavoncat](https://github.com/ameliavoncat)
|
|
||||||
* [ilpianista](https://github.com/ilpianista)
|
|
||||||
* [andydrop](https://github.com/andydrop)
|
|
||||||
* [schas002](https://github.com/schas002)
|
|
||||||
* [jumbosushi](https://github.com/jumbosushi)
|
|
||||||
* [ayumin](https://github.com/ayumin)
|
|
||||||
* [BaptisteGelez](https://github.com/BaptisteGelez)
|
|
||||||
* [bzg](https://github.com/bzg)
|
|
||||||
* [benediktg](https://github.com/benediktg)
|
|
||||||
* [blakebarnett](https://github.com/blakebarnett)
|
|
||||||
* [bradj](https://github.com/bradj)
|
|
||||||
* [brycied00d](https://github.com/brycied00d)
|
|
||||||
* [carlosjs23](https://github.com/carlosjs23)
|
|
||||||
* [cgxxx](https://github.com/cgxxx)
|
|
||||||
* [chrisheninger](https://github.com/chrisheninger)
|
|
||||||
* [chris-martin](https://github.com/chris-martin)
|
|
||||||
* [DoubleMalt](https://github.com/DoubleMalt)
|
|
||||||
* [Moosh-be](https://github.com/Moosh-be)
|
|
||||||
* [Motoma](https://github.com/Motoma)
|
|
||||||
* [chriswk](https://github.com/chriswk)
|
|
||||||
* [csu](https://github.com/csu)
|
|
||||||
* [kklleemm](https://github.com/kklleemm)
|
|
||||||
* [monsterpit-daggertooth](https://github.com/monsterpit-daggertooth)
|
|
||||||
* [watilde](https://github.com/watilde)
|
|
||||||
* [daprice](https://github.com/daprice)
|
|
||||||
* [dar5hak](https://github.com/dar5hak)
|
|
||||||
* [kant](https://github.com/kant)
|
|
||||||
* [singingwolfboy](https://github.com/singingwolfboy)
|
|
||||||
* [davidcelis](https://github.com/davidcelis)
|
|
||||||
* [yipdw](https://github.com/yipdw)
|
|
||||||
* [debanshuk](https://github.com/debanshuk)
|
|
||||||
* [dblandin](https://github.com/dblandin)
|
|
||||||
* [aranaur](https://github.com/aranaur)
|
|
||||||
* [d3vgru](https://github.com/d3vgru)
|
|
||||||
* [Elizafox](https://github.com/Elizafox)
|
|
||||||
* [ericblade](https://github.com/ericblade)
|
|
||||||
* [mikoim](https://github.com/mikoim)
|
|
||||||
* [siuying](https://github.com/siuying)
|
|
||||||
* [hattori6789](https://github.com/hattori6789)
|
|
||||||
* [algernon](https://github.com/algernon)
|
|
||||||
* [Fastbyte01](https://github.com/Fastbyte01)
|
|
||||||
* [myfreeweb](https://github.com/myfreeweb)
|
|
||||||
* [gfaivre](https://github.com/gfaivre)
|
|
||||||
* [Fiaxhs](https://github.com/Fiaxhs)
|
|
||||||
* [reedcourty](https://github.com/reedcourty)
|
|
||||||
* [anneau](https://github.com/anneau)
|
|
||||||
* [HellPie](https://github.com/HellPie)
|
|
||||||
* [Habu-Kagumba](https://github.com/Habu-Kagumba)
|
|
||||||
* [hinaloe](https://github.com/hinaloe)
|
|
||||||
* [suzukaze](https://github.com/suzukaze)
|
|
||||||
* [Hiromi-Kai](https://github.com/Hiromi-Kai)
|
|
||||||
* [musashino205](https://github.com/musashino205)
|
|
||||||
* [iwaim](https://github.com/iwaim)
|
|
||||||
* [valrus](https://github.com/valrus)
|
|
||||||
* [IMcD23](https://github.com/IMcD23)
|
|
||||||
* [yi0713](https://github.com/yi0713)
|
|
||||||
* [immae](https://github.com/immae)
|
|
||||||
* [iblech](https://github.com/iblech)
|
|
||||||
* [jack-michaud](https://github.com/jack-michaud)
|
|
||||||
* [Floppy](https://github.com/Floppy)
|
|
||||||
* [loomchild](https://github.com/loomchild)
|
|
||||||
* [docjkl](https://github.com/docjkl)
|
|
||||||
* [TrollDecker](https://github.com/TrollDecker)
|
|
||||||
* [jmontane](https://github.com/jmontane)
|
|
||||||
* [jonathanklee](https://github.com/jonathanklee)
|
|
||||||
* [jguerder](https://github.com/jguerder)
|
|
||||||
* [Jehops](https://github.com/Jehops)
|
|
||||||
* [joshuap](https://github.com/joshuap)
|
|
||||||
* [Tiwy57](https://github.com/Tiwy57)
|
|
||||||
* [xuv](https://github.com/xuv)
|
|
||||||
* [Jnsll](https://github.com/Jnsll)
|
|
||||||
* [j0k3r](https://github.com/j0k3r)
|
|
||||||
* [KEINOS](https://github.com/KEINOS)
|
|
||||||
* [futoase](https://github.com/futoase)
|
|
||||||
* [abjectio](https://github.com/abjectio)
|
|
||||||
* [mkody](https://github.com/mkody)
|
|
||||||
* [connyduck](https://github.com/connyduck)
|
|
||||||
* [k0ta0uchi](https://github.com/k0ta0uchi)
|
|
||||||
* [KrzysiekJ](https://github.com/KrzysiekJ)
|
|
||||||
* [leowzukw](https://github.com/leowzukw)
|
|
||||||
* [lmorchard](https://github.com/lmorchard)
|
|
||||||
* [cacheflow](https://github.com/cacheflow)
|
|
||||||
* [ldidry](https://github.com/ldidry)
|
|
||||||
* [jemus42](https://github.com/jemus42)
|
|
||||||
* [lfuelling](https://github.com/lfuelling)
|
|
||||||
* [Grabacr07](https://github.com/Grabacr07)
|
|
||||||
* [mistermantas](https://github.com/mistermantas)
|
|
||||||
* [wirehack7](https://github.com/wirehack7)
|
|
||||||
* [marvinkopf](https://github.com/marvinkopf)
|
|
||||||
* [otsune](https://github.com/otsune)
|
|
||||||
* [m-blc](https://github.com/m-blc)
|
|
||||||
* [matt-auckland](https://github.com/matt-auckland)
|
|
||||||
* [mattjmattj](https://github.com/mattjmattj)
|
|
||||||
* [mtparet](https://github.com/mtparet)
|
|
||||||
* [maximeborges](https://github.com/maximeborges)
|
|
||||||
* [minacle](https://github.com/minacle)
|
|
||||||
* [michaeljdeeb](https://github.com/michaeljdeeb)
|
|
||||||
* [Themimitoof](https://github.com/Themimitoof)
|
|
||||||
* [cyweo](https://github.com/cyweo)
|
|
||||||
* [M1dgard](https://github.com/M1dgard)
|
|
||||||
* [mike-burns](https://github.com/mike-burns)
|
|
||||||
* [verymilan](https://github.com/verymilan)
|
|
||||||
* [milmazz](https://github.com/milmazz)
|
|
||||||
* [Mnkai](https://github.com/Mnkai)
|
|
||||||
* [mitchhentges](https://github.com/mitchhentges)
|
|
||||||
* [moritzheiber](https://github.com/moritzheiber)
|
|
||||||
* [mouse-reeve](https://github.com/mouse-reeve)
|
|
||||||
* [lae](https://github.com/lae)
|
|
||||||
* [Nanamachi](https://github.com/Nanamachi)
|
|
||||||
* [ngerakines](https://github.com/ngerakines)
|
|
||||||
* [vonneudeck](https://github.com/vonneudeck)
|
|
||||||
* [Ninetailed](https://github.com/Ninetailed)
|
|
||||||
* [k24](https://github.com/k24)
|
|
||||||
* [noiob](https://github.com/noiob)
|
|
||||||
* [kwaio](https://github.com/kwaio)
|
|
||||||
* [norayr](https://github.com/norayr)
|
|
||||||
* [joyeusenoelle](https://github.com/joyeusenoelle)
|
|
||||||
* [OlivierNicole](https://github.com/OlivierNicole)
|
|
||||||
* [Otakan951](https://github.com/Otakan951)
|
|
||||||
* [fahy](https://github.com/fahy)
|
|
||||||
* [Pangoraw](https://github.com/Pangoraw)
|
|
||||||
* [pwoolcoc](https://github.com/pwoolcoc)
|
|
||||||
* [peterkeen](https://github.com/peterkeen)
|
|
||||||
* [petzah](https://github.com/petzah)
|
|
||||||
* [ignisf](https://github.com/ignisf)
|
|
||||||
* [rfwatson](https://github.com/rfwatson)
|
|
||||||
* [rfreebern](https://github.com/rfreebern)
|
|
||||||
* [sylph01](https://github.com/sylph01)
|
|
||||||
* [staticsafe](https://github.com/staticsafe)
|
|
||||||
* [snwh](https://github.com/snwh)
|
|
||||||
* [skoji](https://github.com/skoji)
|
|
||||||
* [ScienJus](https://github.com/ScienJus)
|
|
||||||
* [larkinscott](https://github.com/larkinscott)
|
|
||||||
* [imolein](https://github.com/imolein)
|
|
||||||
* [blinry](https://github.com/blinry)
|
|
||||||
* [Noiwex](https://github.com/Noiwex)
|
|
||||||
* [yuki764](https://github.com/yuki764)
|
|
||||||
* [shnjp](https://github.com/shnjp)
|
|
||||||
* [ernix](https://github.com/ernix)
|
|
||||||
* [rosylilly](https://github.com/rosylilly)
|
|
||||||
* [shouko](https://github.com/shouko)
|
|
||||||
* [sossii](https://github.com/sossii)
|
|
||||||
* [StefOfficiel](https://github.com/StefOfficiel)
|
|
||||||
* [svetlik](https://github.com/svetlik)
|
|
||||||
* [dereckson](https://github.com/dereckson)
|
|
||||||
* [theboss](https://github.com/theboss)
|
|
||||||
* [takp](https://github.com/takp)
|
|
||||||
* [tkusano](https://github.com/tkusano)
|
|
||||||
* [TheInventrix](https://github.com/TheInventrix)
|
|
||||||
* [shug0](https://github.com/shug0)
|
|
||||||
* [Fortyseven](https://github.com/Fortyseven)
|
|
||||||
* [tobypinder](https://github.com/tobypinder)
|
|
||||||
* [tomosm](https://github.com/tomosm)
|
|
||||||
* [TomoyaShibata](https://github.com/TomoyaShibata)
|
|
||||||
* [TrashMacNugget](https://github.com/TrashMacNugget)
|
|
||||||
* [treyssatvincent](https://github.com/treyssatvincent)
|
|
||||||
* [optikfluffel](https://github.com/optikfluffel)
|
|
||||||
* [vmincev](https://github.com/vmincev)
|
|
||||||
* [waldyrious](https://github.com/waldyrious)
|
|
||||||
* [tahnok](https://github.com/tahnok)
|
|
||||||
* [YDrogen](https://github.com/YDrogen)
|
|
||||||
* [YOSHIOKAEiichiro](https://github.com/YOSHIOKAEiichiro)
|
|
||||||
* [S-YOU](https://github.com/S-YOU)
|
|
||||||
* [YaQ00](https://github.com/YaQ00)
|
|
||||||
* [yanakend](https://github.com/yanakend)
|
|
||||||
* [orzFly](https://github.com/orzFly)
|
|
||||||
* [chansuke](https://github.com/chansuke)
|
|
||||||
* [yuntan](https://github.com/yuntan)
|
|
||||||
* [LogicalDash](https://github.com/LogicalDash)
|
|
||||||
* [ZiiX](https://github.com/ZiiX)
|
|
||||||
* [benklop](https://github.com/benklop)
|
|
||||||
* [caasi](https://github.com/caasi)
|
|
||||||
* [caesarologia](https://github.com/caesarologia)
|
|
||||||
* [chrolis](https://github.com/chrolis)
|
|
||||||
* [cormojs](https://github.com/cormojs)
|
|
||||||
* [cpsdqs](https://github.com/cpsdqs)
|
|
||||||
* [d0p1s4m4](https://github.com/d0p1s4m4)
|
|
||||||
* [evilny0](https://github.com/evilny0)
|
|
||||||
* [febrezo](https://github.com/febrezo)
|
|
||||||
* [fsubal](https://github.com/fsubal)
|
|
||||||
* [dikky1218](https://github.com/dikky1218)
|
|
||||||
* [gentarok](https://github.com/gentarok)
|
|
||||||
* [hakoai](https://github.com/hakoai)
|
|
||||||
* [chaosbunker](https://github.com/chaosbunker)
|
|
||||||
* [isati](https://github.com/isati)
|
|
||||||
* [jkap](https://github.com/jkap)
|
|
||||||
* [jirayudech](https://github.com/jirayudech)
|
|
||||||
* [jukper](https://github.com/jukper)
|
|
||||||
* [karlyeurl](https://github.com/karlyeurl)
|
|
||||||
* [kedamaDQ](https://github.com/kedamaDQ)
|
|
||||||
* [kuro5hin](https://github.com/kuro5hin)
|
|
||||||
* [maxypy](https://github.com/maxypy)
|
|
||||||
* [marcus-herrmann](https://github.com/marcus-herrmann)
|
|
||||||
* [mshrtkch](https://github.com/mshrtkch)
|
|
||||||
* [muan](https://github.com/muan)
|
|
||||||
* [rch850](https://github.com/rch850)
|
|
||||||
* [roikale](https://github.com/roikale)
|
|
||||||
* [rysiekpl](https://github.com/rysiekpl)
|
|
||||||
* [saturday06](https://github.com/saturday06)
|
|
||||||
* [scriptjunkie](https://github.com/scriptjunkie)
|
|
||||||
* [seekr](https://github.com/seekr)
|
|
||||||
* [syui](https://github.com/syui)
|
|
||||||
* [tackeyy](https://github.com/tackeyy)
|
|
||||||
* [tmyt](https://github.com/tmyt)
|
|
||||||
* [utam0k](https://github.com/utam0k)
|
|
||||||
* [vpzomtrrfrt](https://github.com/vpzomtrrfrt)
|
|
||||||
* [walfie](https://github.com/walfie)
|
|
||||||
* [y-temp4](https://github.com/y-temp4)
|
|
||||||
* [ymmtmdk](https://github.com/ymmtmdk)
|
|
||||||
|
|
||||||
This document is provided for informational purposes only. Since it is only updated once per release, the version you are looking at may be currently out of date. To see the full list of contributors, consider looking at the [git history](https://github.com/tootsuite/mastodon/graphs/contributors) instead.
|
|
||||||
1
Aptfile
1
Aptfile
@@ -1,5 +1,4 @@
|
|||||||
ffmpeg
|
ffmpeg
|
||||||
libicu[0-9][0-9]
|
|
||||||
libicu-dev
|
libicu-dev
|
||||||
libidn11
|
libidn11
|
||||||
libidn11-dev
|
libidn11-dev
|
||||||
|
|||||||
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/
|
|
||||||
49
Dockerfile
49
Dockerfile
@@ -1,16 +1,12 @@
|
|||||||
FROM ruby:2.4.4-alpine3.6
|
FROM ruby:2.4.1-alpine3.6
|
||||||
|
|
||||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||||
description="Your self-hosted, globally interconnected microblogging community"
|
description="A GNU Social-compatible microblogging server"
|
||||||
|
|
||||||
ARG UID=991
|
ENV UID=991 GID=991 \
|
||||||
ARG GID=991
|
RAILS_SERVE_STATIC_FILES=true \
|
||||||
|
|
||||||
ENV RAILS_SERVE_STATIC_FILES=true \
|
|
||||||
RAILS_ENV=production NODE_ENV=production
|
RAILS_ENV=production NODE_ENV=production
|
||||||
|
|
||||||
ARG YARN_VERSION=1.3.2
|
|
||||||
ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d
|
|
||||||
ARG LIBICONV_VERSION=1.15
|
ARG LIBICONV_VERSION=1.15
|
||||||
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178
|
||||||
|
|
||||||
@@ -23,7 +19,6 @@ RUN apk -U upgrade \
|
|||||||
build-base \
|
build-base \
|
||||||
icu-dev \
|
icu-dev \
|
||||||
libidn-dev \
|
libidn-dev \
|
||||||
libressl \
|
|
||||||
libtool \
|
libtool \
|
||||||
postgresql-dev \
|
postgresql-dev \
|
||||||
protobuf-dev \
|
protobuf-dev \
|
||||||
@@ -37,21 +32,16 @@ RUN apk -U upgrade \
|
|||||||
imagemagick \
|
imagemagick \
|
||||||
libidn \
|
libidn \
|
||||||
libpq \
|
libpq \
|
||||||
nodejs \
|
|
||||||
nodejs-npm \
|
nodejs-npm \
|
||||||
|
nodejs \
|
||||||
protobuf \
|
protobuf \
|
||||||
|
su-exec \
|
||||||
tini \
|
tini \
|
||||||
tzdata \
|
yarn \
|
||||||
&& update-ca-certificates \
|
&& update-ca-certificates \
|
||||||
&& mkdir -p /tmp/src /opt \
|
&& wget -O libiconv.tar.gz "http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
||||||
&& 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" \
|
|
||||||
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
&& echo "$LIBICONV_DOWNLOAD_SHA256 *libiconv.tar.gz" | sha256sum -c - \
|
||||||
|
&& mkdir -p /tmp/src \
|
||||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
||||||
&& rm libiconv.tar.gz \
|
&& rm libiconv.tar.gz \
|
||||||
&& cd /tmp/src/libiconv-$LIBICONV_VERSION \
|
&& cd /tmp/src/libiconv-$LIBICONV_VERSION \
|
||||||
@@ -62,27 +52,18 @@ RUN apk -U upgrade \
|
|||||||
&& cd /mastodon \
|
&& cd /mastodon \
|
||||||
&& rm -rf /tmp/* /var/cache/apk/*
|
&& 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/
|
||||||
COPY stack-fix.c /lib
|
|
||||||
RUN gcc -shared -fPIC /lib/stack-fix.c -o /lib/stack-fix.so
|
|
||||||
RUN rm /lib/stack-fix.c
|
|
||||||
|
|
||||||
RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-include=/usr/local/include \
|
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 \
|
&& bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without test development \
|
||||||
&& yarn --pure-lockfile \
|
&& yarn --ignore-optional --pure-lockfile
|
||||||
&& yarn cache clean
|
|
||||||
|
|
||||||
RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \
|
|
||||||
&& mkdir -p /mastodon/public/system /mastodon/public/assets /mastodon/public/packs \
|
|
||||||
&& chown -R mastodon:mastodon /mastodon/public
|
|
||||||
|
|
||||||
COPY . /mastodon
|
COPY . /mastodon
|
||||||
|
|
||||||
RUN chown -R mastodon:mastodon /mastodon
|
COPY docker_entrypoint.sh /usr/local/bin/run
|
||||||
|
|
||||||
|
RUN chmod +x /usr/local/bin/run
|
||||||
|
|
||||||
VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
|
VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
|
||||||
|
|
||||||
USER mastodon
|
ENTRYPOINT ["/usr/local/bin/run"]
|
||||||
|
|
||||||
ENV LD_PRELOAD=/lib/stack-fix.so
|
|
||||||
ENTRYPOINT ["/sbin/tini", "--"]
|
|
||||||
|
|||||||
126
Gemfile
126
Gemfile
@@ -1,144 +1,118 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '>= 2.3.0', '< 2.6.0'
|
ruby '>= 2.3.0', '< 2.5.0'
|
||||||
|
|
||||||
gem 'pkg-config', '~> 1.2'
|
gem 'pkg-config', '~> 1.2'
|
||||||
|
|
||||||
gem 'puma', '~> 3.11'
|
gem 'puma', '~> 3.8'
|
||||||
gem 'rails', '~> 5.2.0'
|
gem 'rails', '~> 5.1.0'
|
||||||
|
gem 'uglifier', '~> 3.2'
|
||||||
|
|
||||||
gem 'hamlit-rails', '~> 0.2'
|
gem 'hamlit-rails', '~> 0.2'
|
||||||
gem 'pg', '~> 1.0'
|
gem 'pg', '~> 0.20'
|
||||||
gem 'pghero', '~> 2.1'
|
gem 'pghero', '~> 1.7'
|
||||||
gem 'dotenv-rails', '~> 2.2'
|
gem 'dotenv-rails', '~> 2.2'
|
||||||
|
|
||||||
gem 'aws-sdk-s3', '~> 1.8', require: false
|
gem 'aws-sdk', '~> 2.9'
|
||||||
gem 'fog-core', '~> 1.45'
|
gem 'fog-openstack', '~> 0.1'
|
||||||
gem 'fog-local', '~> 0.4', require: false
|
gem 'paperclip', '~> 5.1'
|
||||||
gem 'fog-openstack', '~> 0.1', require: false
|
|
||||||
gem 'paperclip', '~> 6.0'
|
|
||||||
gem 'paperclip-av-transcoder', '~> 0.6'
|
gem 'paperclip-av-transcoder', '~> 0.6'
|
||||||
gem 'posix-spawn'
|
|
||||||
gem 'streamio-ffmpeg', '~> 3.0'
|
|
||||||
|
|
||||||
gem 'active_model_serializers', '~> 0.10'
|
gem 'active_model_serializers', '~> 0.10'
|
||||||
gem 'addressable', '~> 2.5'
|
gem 'addressable', '~> 2.5'
|
||||||
gem 'bootsnap', '~> 1.3'
|
gem 'bootsnap'
|
||||||
gem 'browser'
|
gem 'browser'
|
||||||
gem 'charlock_holmes', '~> 0.7.6'
|
gem 'charlock_holmes', '~> 0.7.5'
|
||||||
gem 'iso-639'
|
gem 'iso-639'
|
||||||
gem 'chewy', '~> 5.0'
|
gem 'cld3', '~> 3.1'
|
||||||
gem 'cld3', '~> 3.2.0'
|
gem 'devise', '~> 4.2'
|
||||||
gem 'devise', '~> 4.4'
|
gem 'devise-two-factor', '~> 3.0'
|
||||||
gem 'devise-two-factor', '~> 3.0', git: 'https://github.com/ykzts/devise-two-factor.git', branch: 'rails-5.2'
|
gem 'doorkeeper', '~> 4.2'
|
||||||
|
|
||||||
group :pam_authentication, optional: true do
|
|
||||||
gem 'devise_pam_authenticatable2', '~> 9.1'
|
|
||||||
end
|
|
||||||
|
|
||||||
gem 'net-ldap', '~> 0.10'
|
|
||||||
gem 'omniauth-cas', '~> 1.1'
|
|
||||||
gem 'omniauth-saml', '~> 1.10'
|
|
||||||
gem 'omniauth', '~> 1.2'
|
|
||||||
|
|
||||||
gem 'doorkeeper', '~> 4.3'
|
|
||||||
gem 'fast_blank', '~> 1.0'
|
gem 'fast_blank', '~> 1.0'
|
||||||
gem 'fastimage'
|
gem 'goldfinger', '~> 2.0'
|
||||||
gem 'goldfinger', '~> 2.1'
|
|
||||||
gem 'hiredis', '~> 0.6'
|
gem 'hiredis', '~> 0.6'
|
||||||
gem 'redis-namespace', '~> 1.5'
|
gem 'redis-namespace', '~> 1.5'
|
||||||
gem 'html2text'
|
|
||||||
gem 'htmlentities', '~> 4.3'
|
gem 'htmlentities', '~> 4.3'
|
||||||
gem 'http', '~> 3.0'
|
gem 'http', '~> 2.2'
|
||||||
gem 'http_accept_language', '~> 2.1'
|
gem 'http_accept_language', '~> 2.1'
|
||||||
gem 'httplog', '~> 1.0'
|
gem 'httplog', '~> 0.99'
|
||||||
gem 'idn-ruby', require: 'idn'
|
gem 'idn-ruby', require: 'idn'
|
||||||
gem 'kaminari', '~> 1.1'
|
gem 'kaminari', '~> 1.0'
|
||||||
gem 'link_header', '~> 0.0'
|
gem 'link_header', '~> 0.0'
|
||||||
gem 'mime-types', '~> 3.1'
|
gem 'mime-types', '~> 3.1'
|
||||||
gem 'nokogiri', '~> 1.8'
|
gem 'nokogiri', '~> 1.7'
|
||||||
gem 'nsa', '~> 0.2'
|
gem 'oj', '~> 3.0'
|
||||||
gem 'oj', '~> 3.4'
|
|
||||||
gem 'ostatus2', '~> 2.0'
|
gem 'ostatus2', '~> 2.0'
|
||||||
gem 'ox', '~> 2.8'
|
gem 'ox', '~> 2.5'
|
||||||
gem 'pundit', '~> 1.1'
|
gem 'pundit', '~> 1.1'
|
||||||
gem 'premailer-rails'
|
gem 'rabl', '~> 0.13'
|
||||||
gem 'rack-attack', '~> 5.2'
|
gem 'rack-attack', '~> 5.0'
|
||||||
gem 'rack-cors', '~> 1.0', require: 'rack/cors'
|
gem 'rack-cors', '~> 0.4', require: 'rack/cors'
|
||||||
gem 'rack-timeout', '~> 0.4'
|
gem 'rack-timeout', '~> 0.4'
|
||||||
gem 'rails-i18n', '~> 5.1'
|
gem 'rails-i18n', '~> 5.0'
|
||||||
gem 'rails-settings-cached', '~> 0.6'
|
gem 'rails-settings-cached', '~> 0.6'
|
||||||
gem 'redis', '~> 4.0', require: ['redis', 'redis/connection/hiredis']
|
gem 'redis', '~> 3.3', require: ['redis', 'redis/connection/hiredis']
|
||||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||||
gem 'rqrcode', '~> 0.10'
|
gem 'rqrcode', '~> 0.10'
|
||||||
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
|
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
|
||||||
gem 'ruby-progressbar', '~> 1.4'
|
gem 'sanitize', '~> 4.4'
|
||||||
gem 'sanitize', '~> 4.6'
|
gem 'sidekiq', '~> 5.0'
|
||||||
gem 'sidekiq', '~> 5.1'
|
gem 'sidekiq-scheduler', '~> 2.1'
|
||||||
gem 'sidekiq-scheduler', '~> 2.2'
|
|
||||||
gem 'sidekiq-unique-jobs', '~> 5.0'
|
gem 'sidekiq-unique-jobs', '~> 5.0'
|
||||||
gem 'sidekiq-bulk', '~>0.1.1'
|
gem 'sidekiq-bulk', '~>0.1.1'
|
||||||
gem 'simple-navigation', '~> 4.0'
|
gem 'simple-navigation', '~> 4.0'
|
||||||
gem 'simple_form', '~> 4.0'
|
gem 'simple_form', '~> 3.4'
|
||||||
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
||||||
gem 'stoplight', '~> 2.1.3'
|
gem 'statsd-instrument', '~> 2.1'
|
||||||
gem 'strong_migrations', '~> 0.2'
|
|
||||||
gem 'tty-command'
|
|
||||||
gem 'tty-prompt'
|
|
||||||
gem 'twitter-text', '~> 1.14'
|
gem 'twitter-text', '~> 1.14'
|
||||||
gem 'tzinfo-data', '~> 1.2018'
|
gem 'tzinfo-data', '~> 1.2017'
|
||||||
gem 'webpacker', '~> 3.4'
|
gem 'webpacker', '~> 2.0'
|
||||||
gem 'webpush'
|
gem 'webpush'
|
||||||
|
|
||||||
gem 'json-ld-preloaded', '~> 2.2'
|
gem 'json-ld-preloaded', '~> 2.2.1'
|
||||||
gem 'rdf-normalize', '~> 0.3'
|
gem 'rdf-normalize', '~> 0.3.1'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'fabrication', '~> 2.20'
|
gem 'fabrication', '~> 2.16'
|
||||||
gem 'fuubar', '~> 2.2'
|
gem 'fuubar', '~> 2.2'
|
||||||
gem 'i18n-tasks', '~> 0.9', require: false
|
gem 'i18n-tasks', '~> 0.9', require: false
|
||||||
gem 'pry-rails', '~> 0.3'
|
gem 'pry-rails', '~> 0.3'
|
||||||
gem 'rspec-rails', '~> 3.7'
|
gem 'rspec-rails', '~> 3.6'
|
||||||
end
|
|
||||||
|
|
||||||
group :production, :test do
|
|
||||||
gem 'private_address_check', '~> 0.4.1'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara', '~> 2.18'
|
gem 'capybara', '~> 2.14'
|
||||||
gem 'climate_control', '~> 0.2'
|
gem 'climate_control', '~> 0.2'
|
||||||
gem 'faker', '~> 1.8'
|
gem 'faker', '~> 1.7'
|
||||||
gem 'microformats', '~> 4.0'
|
gem 'microformats', '~> 4.0'
|
||||||
gem 'rails-controller-testing', '~> 1.0'
|
gem 'rails-controller-testing', '~> 1.0'
|
||||||
gem 'rspec-sidekiq', '~> 3.0'
|
gem 'rspec-sidekiq', '~> 3.0'
|
||||||
gem 'simplecov', '~> 0.14', require: false
|
gem 'simplecov', '~> 0.14', require: false
|
||||||
gem 'webmock', '~> 3.3'
|
gem 'webmock', '~> 3.0'
|
||||||
gem 'parallel_tests', '~> 2.21'
|
gem 'parallel_tests', '~> 2.14'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'active_record_query_trace', '~> 1.5'
|
gem 'active_record_query_trace', '~> 1.5'
|
||||||
gem 'annotate', '~> 2.7'
|
gem 'annotate', '~> 2.7'
|
||||||
gem 'better_errors', '~> 2.4'
|
gem 'better_errors', '~> 2.1'
|
||||||
gem 'binding_of_caller', '~> 0.7'
|
gem 'binding_of_caller', '~> 0.7'
|
||||||
gem 'bullet', '~> 5.7'
|
gem 'bullet', '~> 5.5'
|
||||||
gem 'letter_opener', '~> 1.4'
|
gem 'letter_opener', '~> 1.4'
|
||||||
gem 'letter_opener_web', '~> 1.3'
|
gem 'letter_opener_web', '~> 1.3'
|
||||||
gem 'memory_profiler'
|
|
||||||
gem 'rubocop', require: false
|
gem 'rubocop', require: false
|
||||||
gem 'brakeman', '~> 4.2', require: false
|
gem 'brakeman', '~> 3.6', require: false
|
||||||
gem 'bundler-audit', '~> 0.6', require: false
|
gem 'bundler-audit', '~> 0.5', require: false
|
||||||
gem 'scss_lint', '~> 0.55', require: false
|
gem 'scss_lint', '~> 0.53', require: false
|
||||||
|
|
||||||
gem 'capistrano', '~> 3.10'
|
gem 'capistrano', '~> 3.8'
|
||||||
gem 'capistrano-rails', '~> 1.3'
|
gem 'capistrano-rails', '~> 1.2'
|
||||||
gem 'capistrano-rbenv', '~> 2.1'
|
gem 'capistrano-rbenv', '~> 2.1'
|
||||||
gem 'capistrano-yarn', '~> 2.0'
|
gem 'capistrano-yarn', '~> 2.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production do
|
group :production do
|
||||||
gem 'lograge', '~> 0.9'
|
gem 'lograge', '~> 0.5'
|
||||||
gem 'redis-rails', '~> 5.0'
|
gem 'redis-rails', '~> 5.0'
|
||||||
end
|
end
|
||||||
|
|||||||
728
Gemfile.lock
728
Gemfile.lock
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
web: env PORT=3000 bundle exec puma -C config/puma.rb
|
web: PORT=3000 bundle exec puma -C config/puma.rb
|
||||||
sidekiq: env PORT=3000 bundle exec sidekiq
|
sidekiq: PORT=3000 bundle exec sidekiq
|
||||||
stream: env PORT=4000 yarn run start
|
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
|
||||||
|
|||||||
7
Vagrantfile
vendored
7
Vagrantfile
vendored
@@ -39,7 +39,6 @@ sudo apt-get install \
|
|||||||
libidn11-dev \
|
libidn11-dev \
|
||||||
libprotobuf-dev \
|
libprotobuf-dev \
|
||||||
libreadline-dev \
|
libreadline-dev \
|
||||||
libpam0g-dev \
|
|
||||||
-y
|
-y
|
||||||
|
|
||||||
# Install rvm
|
# Install rvm
|
||||||
@@ -49,7 +48,7 @@ curl -sSL https://raw.githubusercontent.com/rvm/rvm/stable/binscripts/rvm-instal
|
|||||||
source /home/vagrant/.rvm/scripts/rvm
|
source /home/vagrant/.rvm/scripts/rvm
|
||||||
|
|
||||||
# Install Ruby
|
# Install Ruby
|
||||||
rvm reinstall ruby-$RUBY_VERSION --disable-binary
|
rvm install ruby-$RUBY_VERSION
|
||||||
|
|
||||||
# Configure database
|
# Configure database
|
||||||
sudo -u postgres createuser -U postgres vagrant -s
|
sudo -u postgres createuser -U postgres vagrant -s
|
||||||
@@ -80,11 +79,11 @@ VAGRANTFILE_API_VERSION = "2"
|
|||||||
|
|
||||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
|
|
||||||
config.vm.box = "ubuntu/xenial64"
|
config.vm.box = "ubuntu/trusty64"
|
||||||
|
|
||||||
config.vm.provider :virtualbox do |vb|
|
config.vm.provider :virtualbox do |vb|
|
||||||
vb.name = "mastodon"
|
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.
|
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
|
||||||
# https://github.com/mitchellh/vagrant/issues/1172
|
# https://github.com/mitchellh/vagrant/issues/1172
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class StatusesIndex < Chewy::Index
|
|
||||||
settings index: { refresh_interval: '15m' }, analysis: {
|
|
||||||
filter: {
|
|
||||||
english_stop: {
|
|
||||||
type: 'stop',
|
|
||||||
stopwords: '_english_',
|
|
||||||
},
|
|
||||||
english_stemmer: {
|
|
||||||
type: 'stemmer',
|
|
||||||
language: 'english',
|
|
||||||
},
|
|
||||||
english_possessive_stemmer: {
|
|
||||||
type: 'stemmer',
|
|
||||||
language: 'possessive_english',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
analyzer: {
|
|
||||||
content: {
|
|
||||||
tokenizer: 'uax_url_email',
|
|
||||||
filter: %w(
|
|
||||||
english_possessive_stemmer
|
|
||||||
lowercase
|
|
||||||
asciifolding
|
|
||||||
cjk_width
|
|
||||||
english_stop
|
|
||||||
english_stemmer
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
define_type ::Status.without_reblogs do
|
|
||||||
crutch :mentions do |collection|
|
|
||||||
data = ::Mention.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
|
|
||||||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
|
||||||
end
|
|
||||||
|
|
||||||
crutch :favourites do |collection|
|
|
||||||
data = ::Favourite.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
|
|
||||||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
|
||||||
end
|
|
||||||
|
|
||||||
crutch :reblogs do |collection|
|
|
||||||
data = ::Status.where(reblog_of_id: collection.map(&:id)).pluck(:reblog_of_id, :account_id)
|
|
||||||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
|
||||||
end
|
|
||||||
|
|
||||||
root date_detection: false do
|
|
||||||
field :account_id, type: 'long'
|
|
||||||
|
|
||||||
field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].join("\n\n") } do
|
|
||||||
field :stemmed, type: 'text', analyzer: 'content'
|
|
||||||
end
|
|
||||||
|
|
||||||
field :searchable_by, type: 'long', value: ->(status, crutches) { status.searchable_by(crutches) }
|
|
||||||
field :created_at, type: 'date'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AboutController < ApplicationController
|
class AboutController < ApplicationController
|
||||||
before_action :set_pack
|
|
||||||
before_action :set_body_classes
|
before_action :set_body_classes
|
||||||
before_action :set_instance_presenter, only: [:show, :more, :terms]
|
before_action :set_instance_presenter, only: [:show, :more, :terms]
|
||||||
|
|
||||||
@@ -22,10 +21,6 @@ class AboutController < ApplicationController
|
|||||||
|
|
||||||
helper_method :new_user
|
helper_method :new_user
|
||||||
|
|
||||||
def set_pack
|
|
||||||
use_pack action_name == 'show' ? 'about' : 'common'
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_instance_presenter
|
def set_instance_presenter
|
||||||
@instance_presenter = InstancePresenter.new
|
@instance_presenter = InstancePresenter.new
|
||||||
end
|
end
|
||||||
@@ -36,7 +31,7 @@ class AboutController < ApplicationController
|
|||||||
|
|
||||||
def initial_state_params
|
def initial_state_params
|
||||||
{
|
{
|
||||||
settings: { known_fediverse: Setting.show_known_fediverse_at_about_page },
|
settings: {},
|
||||||
token: current_session&.token,
|
token: current_session&.token,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountsController < ApplicationController
|
class AccountsController < ApplicationController
|
||||||
PAGE_SIZE = 20
|
|
||||||
|
|
||||||
include AccountControllerConcern
|
include AccountControllerConcern
|
||||||
|
include SignatureVerification
|
||||||
before_action :set_cache_headers
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
use_pack 'public'
|
|
||||||
@pinned_statuses = []
|
@pinned_statuses = []
|
||||||
|
|
||||||
if current_account && @account.blocking?(current_account)
|
if current_account && @account.blocking?(current_account)
|
||||||
@@ -19,25 +15,18 @@ class AccountsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
|
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
|
||||||
@statuses = filtered_status_page(params)
|
@statuses = filtered_statuses.paginate_by_max_id(20, params[:max_id], params[:since_id])
|
||||||
@statuses = cache_collection(@statuses, Status)
|
@statuses = cache_collection(@statuses, Status)
|
||||||
unless @statuses.empty?
|
@next_url = next_url unless @statuses.empty?
|
||||||
@older_url = older_url if @statuses.last.id > filtered_statuses.last.id
|
|
||||||
@newer_url = newer_url if @statuses.first.id < filtered_statuses.first.id
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
format.atom do
|
format.atom do
|
||||||
@entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id])
|
@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.reject { |entry| entry.status.nil? }))
|
||||||
end
|
end
|
||||||
|
|
||||||
format.json do
|
format.json do
|
||||||
skip_session!
|
render json: @account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||||
|
|
||||||
render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do
|
|
||||||
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -56,7 +45,7 @@ class AccountsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def default_statuses
|
def default_statuses
|
||||||
@account.statuses.not_local_only.where(visibility: [:public, :unlisted])
|
@account.statuses.where(visibility: [:public, :unlisted])
|
||||||
end
|
end
|
||||||
|
|
||||||
def only_media_scope
|
def only_media_scope
|
||||||
@@ -75,22 +64,13 @@ class AccountsController < ApplicationController
|
|||||||
@account = Account.find_local!(params[:username])
|
@account = Account.find_local!(params[:username])
|
||||||
end
|
end
|
||||||
|
|
||||||
def older_url
|
def next_url
|
||||||
::Rails.logger.info("older: max_id #{@statuses.last.id}, url #{pagination_url(max_id: @statuses.last.id)}")
|
|
||||||
pagination_url(max_id: @statuses.last.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def newer_url
|
|
||||||
pagination_url(min_id: @statuses.first.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_url(max_id: nil, min_id: nil)
|
|
||||||
if media_requested?
|
if media_requested?
|
||||||
short_account_media_url(@account, max_id: max_id, min_id: min_id)
|
short_account_media_url(@account, max_id: @statuses.last.id)
|
||||||
elsif replies_requested?
|
elsif replies_requested?
|
||||||
short_account_with_replies_url(@account, max_id: max_id, min_id: min_id)
|
short_account_with_replies_url(@account, max_id: @statuses.last.id)
|
||||||
else
|
else
|
||||||
short_account_url(@account, max_id: max_id, min_id: min_id)
|
short_account_url(@account, max_id: @statuses.last.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -101,12 +81,4 @@ class AccountsController < ApplicationController
|
|||||||
def replies_requested?
|
def replies_requested?
|
||||||
request.path.ends_with?('/with_replies')
|
request.path.ends_with?('/with_replies')
|
||||||
end
|
end
|
||||||
|
|
||||||
def filtered_status_page(params)
|
|
||||||
if params[:min_id].present?
|
|
||||||
filtered_statuses.paginate_by_min_id(PAGE_SIZE, params[:min_id]).reverse
|
|
||||||
else
|
|
||||||
filtered_statuses.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id]).to_a
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class ActivityPub::CollectionsController < Api::BaseController
|
|
||||||
include SignatureVerification
|
|
||||||
|
|
||||||
before_action :set_account
|
|
||||||
before_action :set_size
|
|
||||||
before_action :set_statuses
|
|
||||||
|
|
||||||
def show
|
|
||||||
render json: collection_presenter,
|
|
||||||
serializer: ActivityPub::CollectionSerializer,
|
|
||||||
adapter: ActivityPub::Adapter,
|
|
||||||
content_type: 'application/activity+json',
|
|
||||||
skip_activities: true
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_account
|
|
||||||
@account = Account.find_local!(params[:account_username])
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_statuses
|
|
||||||
@statuses = scope_for_collection.paginate_by_max_id(20, params[:max_id], params[:since_id])
|
|
||||||
@statuses = cache_collection(@statuses, Status)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_size
|
|
||||||
case params[:id]
|
|
||||||
when 'featured'
|
|
||||||
@account.pinned_statuses.count
|
|
||||||
else
|
|
||||||
raise ActiveRecord::NotFound
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def scope_for_collection
|
|
||||||
case params[:id]
|
|
||||||
when 'featured'
|
|
||||||
@account.statuses.permitted_for(@account, signed_request_account).tap do |scope|
|
|
||||||
scope.merge!(@account.pinned_statuses)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
raise ActiveRecord::NotFound
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def collection_presenter
|
|
||||||
ActivityPub::CollectionPresenter.new(
|
|
||||||
id: account_collection_url(@account, params[:id]),
|
|
||||||
type: :ordered,
|
|
||||||
size: @size,
|
|
||||||
items: @statuses
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -9,9 +9,9 @@ class ActivityPub::InboxesController < Api::BaseController
|
|||||||
if signed_request_account
|
if signed_request_account
|
||||||
upgrade_account
|
upgrade_account
|
||||||
process_payload
|
process_payload
|
||||||
head 202
|
head 201
|
||||||
else
|
else
|
||||||
render plain: signature_verification_failure_reason, status: 401
|
head 202
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -28,11 +28,10 @@ class ActivityPub::InboxesController < Api::BaseController
|
|||||||
def upgrade_account
|
def upgrade_account
|
||||||
if signed_request_account.ostatus?
|
if signed_request_account.ostatus?
|
||||||
signed_request_account.update(last_webfingered_at: nil)
|
signed_request_account.update(last_webfingered_at: nil)
|
||||||
ResolveAccountWorker.perform_async(signed_request_account.acct)
|
ResolveRemoteAccountWorker.perform_async(signed_request_account.acct)
|
||||||
end
|
end
|
||||||
|
|
||||||
Pubsubhubbub::UnsubscribeWorker.perform_async(signed_request_account.id) if signed_request_account.subscribed?
|
Pubsubhubbub::UnsubscribeWorker.perform_async(signed_request_account.id) if signed_request_account.subscribed?
|
||||||
DeliveryFailureTracker.track_inverse_success!(signed_request_account)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_payload
|
def process_payload
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::OutboxesController < Api::BaseController
|
class ActivityPub::OutboxesController < Api::BaseController
|
||||||
include SignatureVerification
|
|
||||||
|
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = @account.statuses.permitted_for(@account, signed_request_account).paginate_by_max_id(20, params[:max_id], params[:since_id])
|
@statuses = @account.statuses.permitted_for(@account, current_account).paginate_by_max_id(20, params[:max_id], params[:since_id])
|
||||||
@statuses = cache_collection(@statuses, Status)
|
@statuses = cache_collection(@statuses, Status)
|
||||||
|
|
||||||
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
render json: outbox_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -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
|
module Admin
|
||||||
class AccountsController < BaseController
|
class AccountsController < BaseController
|
||||||
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload, :remove_avatar, :enable, :disable, :memorialize]
|
before_action :set_account, only: [:show, :subscribe, :unsubscribe, :redownload]
|
||||||
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
|
before_action :require_remote_account!, only: [:subscribe, :unsubscribe, :redownload]
|
||||||
before_action :require_local_account!, only: [:enable, :disable, :memorialize]
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :account, :index?
|
|
||||||
@accounts = filtered_accounts.page(params[:page])
|
@accounts = filtered_accounts.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show; end
|
||||||
authorize @account, :show?
|
|
||||||
@account_moderation_note = current_account.account_moderation_notes.new(target_account: @account)
|
|
||||||
@moderation_notes = @account.targeted_moderation_notes.latest
|
|
||||||
end
|
|
||||||
|
|
||||||
def subscribe
|
def subscribe
|
||||||
authorize @account, :subscribe?
|
|
||||||
Pubsubhubbub::SubscribeWorker.perform_async(@account.id)
|
Pubsubhubbub::SubscribeWorker.perform_async(@account.id)
|
||||||
redirect_to admin_account_path(@account.id)
|
redirect_to admin_account_path(@account.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unsubscribe
|
def unsubscribe
|
||||||
authorize @account, :unsubscribe?
|
|
||||||
Pubsubhubbub::UnsubscribeWorker.perform_async(@account.id)
|
Pubsubhubbub::UnsubscribeWorker.perform_async(@account.id)
|
||||||
redirect_to admin_account_path(@account.id)
|
redirect_to admin_account_path(@account.id)
|
||||||
end
|
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
|
def redownload
|
||||||
authorize @account, :redownload?
|
|
||||||
|
|
||||||
@account.reset_avatar!
|
@account.reset_avatar!
|
||||||
@account.reset_header!
|
@account.reset_header!
|
||||||
@account.save!
|
@account.save!
|
||||||
@@ -60,17 +29,6 @@ module Admin
|
|||||||
redirect_to admin_account_path(@account.id)
|
redirect_to admin_account_path(@account.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_avatar
|
|
||||||
authorize @account, :remove_avatar?
|
|
||||||
|
|
||||||
@account.avatar = nil
|
|
||||||
@account.save!
|
|
||||||
|
|
||||||
log_action :remove_avatar, @account.user
|
|
||||||
|
|
||||||
redirect_to admin_account_path(@account.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_account
|
def set_account
|
||||||
@@ -81,10 +39,6 @@ module Admin
|
|||||||
redirect_to admin_account_path(@account.id) if @account.local?
|
redirect_to admin_account_path(@account.id) if @account.local?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_local_account!
|
|
||||||
redirect_to admin_account_path(@account.id) unless @account.local? && @account.user.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def filtered_accounts
|
def filtered_accounts
|
||||||
AccountFilter.new(filter_params).results
|
AccountFilter.new(filter_params).results
|
||||||
end
|
end
|
||||||
@@ -100,8 +54,7 @@ module Admin
|
|||||||
:username,
|
:username,
|
||||||
:display_name,
|
:display_name,
|
||||||
:email,
|
:email,
|
||||||
:ip,
|
:ip
|
||||||
:staff
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
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,17 +2,8 @@
|
|||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class BaseController < ApplicationController
|
class BaseController < ApplicationController
|
||||||
include Authorization
|
before_action :require_admin!
|
||||||
include AccountableConcern
|
|
||||||
|
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :require_staff!
|
|
||||||
before_action :set_pack
|
|
||||||
|
|
||||||
def set_pack
|
|
||||||
use_pack 'admin'
|
|
||||||
use_pack 'public'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class ChangeEmailsController < BaseController
|
|
||||||
before_action :set_account
|
|
||||||
before_action :require_local_account!
|
|
||||||
|
|
||||||
def show
|
|
||||||
authorize @user, :change_email?
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
authorize @user, :change_email?
|
|
||||||
|
|
||||||
new_email = resource_params.fetch(:unconfirmed_email)
|
|
||||||
|
|
||||||
if new_email != @user.email
|
|
||||||
@user.update!(
|
|
||||||
unconfirmed_email: new_email,
|
|
||||||
# Regenerate the confirmation token:
|
|
||||||
confirmation_token: nil
|
|
||||||
)
|
|
||||||
|
|
||||||
log_action :change_email, @user
|
|
||||||
|
|
||||||
@user.send_confirmation_instructions
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_account_path(@account.id), notice: I18n.t('admin.accounts.change_email.changed_msg')
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_account
|
|
||||||
@account = Account.find(params[:account_id])
|
|
||||||
@user = @account.user
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_local_account!
|
|
||||||
redirect_to admin_account_path(@account.id) unless @account.local? && @account.user.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.require(:user).permit(
|
|
||||||
:unconfirmed_email
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -2,19 +2,15 @@
|
|||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class ConfirmationsController < BaseController
|
class ConfirmationsController < BaseController
|
||||||
before_action :set_user
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @user, :confirm?
|
account_user.confirm
|
||||||
@user.confirm!
|
|
||||||
log_action :confirm, @user
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_user
|
def account_user
|
||||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,111 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class CustomEmojisController < BaseController
|
|
||||||
before_action :set_custom_emoji, except: [:index, :new, :create]
|
|
||||||
before_action :set_filter_params
|
|
||||||
|
|
||||||
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
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.updated_msg')
|
|
||||||
else
|
|
||||||
flash[:alert] = I18n.t('admin.custom_emojis.update_failed_msg')
|
|
||||||
end
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
authorize @custom_emoji, :destroy?
|
|
||||||
@custom_emoji.destroy!
|
|
||||||
log_action :destroy, @custom_emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.destroyed_msg')
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
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], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def enable
|
|
||||||
authorize @custom_emoji, :enable?
|
|
||||||
@custom_emoji.update!(disabled: false)
|
|
||||||
log_action :enable, @custom_emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.enabled_msg')
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def disable
|
|
||||||
authorize @custom_emoji, :disable?
|
|
||||||
@custom_emoji.update!(disabled: true)
|
|
||||||
log_action :disable, @custom_emoji
|
|
||||||
flash[:notice] = I18n.t('admin.custom_emojis.disabled_msg')
|
|
||||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_custom_emoji
|
|
||||||
@custom_emoji = CustomEmoji.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_filter_params
|
|
||||||
@filter_params = filter_params.to_hash.symbolize_keys
|
|
||||||
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]
|
before_action :set_domain_block, only: [:show, :destroy]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :domain_block, :index?
|
|
||||||
@domain_blocks = DomainBlock.page(params[:page])
|
@domain_blocks = DomainBlock.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
authorize :domain_block, :create?
|
|
||||||
@domain_block = DomainBlock.new
|
@domain_block = DomainBlock.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize :domain_block, :create?
|
|
||||||
|
|
||||||
@domain_block = DomainBlock.new(resource_params)
|
@domain_block = DomainBlock.new(resource_params)
|
||||||
|
|
||||||
if @domain_block.save
|
if @domain_block.save
|
||||||
DomainBlockWorker.perform_async(@domain_block.id)
|
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')
|
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.created_msg')
|
||||||
else
|
else
|
||||||
render :new
|
render :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show; end
|
||||||
authorize @domain_block, :show?
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @domain_block, :destroy?
|
|
||||||
UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
|
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')
|
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.destroyed_msg')
|
||||||
end
|
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
|
module Admin
|
||||||
class InstancesController < BaseController
|
class InstancesController < BaseController
|
||||||
def index
|
def index
|
||||||
authorize :instance, :index?
|
|
||||||
@instances = ordered_instances
|
@instances = ordered_instances
|
||||||
end
|
end
|
||||||
|
|
||||||
def resubscribe
|
def resubscribe
|
||||||
authorize :instance, :resubscribe?
|
|
||||||
params.require(:by_domain)
|
params.require(:by_domain)
|
||||||
Pubsubhubbub::SubscribeWorker.push_bulk(subscribeable_accounts.pluck(:id))
|
Pubsubhubbub::SubscribeWorker.push_bulk(subscribeable_accounts.pluck(:id))
|
||||||
redirect_to admin_instances_path
|
redirect_to admin_instances_path
|
||||||
@@ -16,12 +14,8 @@ module Admin
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def filtered_instances
|
|
||||||
InstanceFilter.new(filter_params).results
|
|
||||||
end
|
|
||||||
|
|
||||||
def paginated_instances
|
def paginated_instances
|
||||||
filtered_instances.page(params[:page])
|
Account.remote.by_domain_accounts.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
helper_method :paginated_instances
|
helper_method :paginated_instances
|
||||||
@@ -33,11 +27,5 @@ module Admin
|
|||||||
def subscribeable_accounts
|
def subscribeable_accounts
|
||||||
Account.with_followers.remote.where(domain: params[:by_domain])
|
Account.with_followers.remote.where(domain: params[:by_domain])
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter_params
|
|
||||||
params.permit(
|
|
||||||
:domain_name
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
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
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class ReportNotesController < BaseController
|
|
||||||
before_action :set_report_note, only: [:destroy]
|
|
||||||
|
|
||||||
def create
|
|
||||||
authorize ReportNote, :create?
|
|
||||||
|
|
||||||
@report_note = current_account.report_notes.new(resource_params)
|
|
||||||
@report = @report_note.report
|
|
||||||
|
|
||||||
if @report_note.save
|
|
||||||
if params[:create_and_resolve]
|
|
||||||
@report.resolve!(current_account)
|
|
||||||
log_action :resolve, @report
|
|
||||||
|
|
||||||
redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:create_and_unresolve]
|
|
||||||
@report.unresolve!
|
|
||||||
log_action :reopen, @report
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_report_path(@report), notice: I18n.t('admin.report_notes.created_msg')
|
|
||||||
else
|
|
||||||
@report_notes = @report.notes.latest
|
|
||||||
@report_history = @report.history
|
|
||||||
@form = Form::StatusBatch.new
|
|
||||||
|
|
||||||
render template: 'admin/reports/show'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
authorize @report_note, :destroy?
|
|
||||||
@report_note.destroy!
|
|
||||||
redirect_to admin_report_path(@report_note.report_id), notice: I18n.t('admin.report_notes.destroyed_msg')
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.require(:report_note).permit(
|
|
||||||
:content,
|
|
||||||
:report_id
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_report_note
|
|
||||||
@report_note = ReportNote.find(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -2,29 +2,26 @@
|
|||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class ReportedStatusesController < BaseController
|
class ReportedStatusesController < BaseController
|
||||||
|
include Authorization
|
||||||
|
|
||||||
before_action :set_report
|
before_action :set_report
|
||||||
before_action :set_status, only: [:update, :destroy]
|
before_action :set_status, only: [:update, :destroy]
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize :status, :update?
|
@form = Form::StatusBatch.new(form_status_batch_params)
|
||||||
|
flash[:alert] = t('admin.statuses.failed_to_execute') unless @form.save
|
||||||
@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
|
|
||||||
|
|
||||||
redirect_to admin_report_path(@report)
|
redirect_to admin_report_path(@report)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize @status, :update?
|
@status.update(status_params)
|
||||||
@status.update!(status_params)
|
|
||||||
log_action :update, @status
|
|
||||||
redirect_to admin_report_path(@report)
|
redirect_to admin_report_path(@report)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @status, :destroy?
|
authorize @status, :destroy?
|
||||||
RemovalWorker.perform_async(@status.id)
|
RemovalWorker.perform_async(@status.id)
|
||||||
log_action :destroy, @status
|
|
||||||
render json: @status
|
render json: @status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,67 +5,43 @@ module Admin
|
|||||||
before_action :set_report, except: [:index]
|
before_action :set_report, except: [:index]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :report, :index?
|
|
||||||
@reports = filtered_reports.page(params[:page])
|
@reports = filtered_reports.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
authorize @report, :show?
|
|
||||||
@report_note = @report.notes.new
|
|
||||||
@report_notes = @report.notes.latest
|
|
||||||
@report_history = @report.history
|
|
||||||
@form = Form::StatusBatch.new
|
@form = Form::StatusBatch.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize @report, :update?
|
|
||||||
process_report
|
process_report
|
||||||
|
|
||||||
if @report.action_taken?
|
|
||||||
redirect_to admin_reports_path, notice: I18n.t('admin.reports.resolved_msg')
|
|
||||||
else
|
|
||||||
redirect_to admin_report_path(@report)
|
redirect_to admin_report_path(@report)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def process_report
|
def process_report
|
||||||
case params[:outcome].to_s
|
case params[:outcome].to_s
|
||||||
when 'assign_to_self'
|
|
||||||
@report.update!(assigned_account_id: current_account.id)
|
|
||||||
log_action :assigned_to_self, @report
|
|
||||||
when 'unassign'
|
|
||||||
@report.update!(assigned_account_id: nil)
|
|
||||||
log_action :unassigned, @report
|
|
||||||
when 'reopen'
|
|
||||||
@report.unresolve!
|
|
||||||
log_action :reopen, @report
|
|
||||||
when 'resolve'
|
when 'resolve'
|
||||||
@report.resolve!(current_account)
|
@report.update(action_taken_by_current_attributes)
|
||||||
log_action :resolve, @report
|
|
||||||
when 'suspend'
|
when 'suspend'
|
||||||
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
||||||
|
|
||||||
log_action :resolve, @report
|
|
||||||
log_action :suspend, @report.target_account
|
|
||||||
|
|
||||||
resolve_all_target_account_reports
|
resolve_all_target_account_reports
|
||||||
when 'silence'
|
when 'silence'
|
||||||
@report.target_account.update!(silenced: true)
|
@report.target_account.update(silenced: true)
|
||||||
|
|
||||||
log_action :resolve, @report
|
|
||||||
log_action :silence, @report.target_account
|
|
||||||
|
|
||||||
resolve_all_target_account_reports
|
resolve_all_target_account_reports
|
||||||
else
|
else
|
||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
@report.reload
|
end
|
||||||
|
|
||||||
|
def action_taken_by_current_attributes
|
||||||
|
{ action_taken: true, action_taken_by_account_id: current_account.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
def resolve_all_target_account_reports
|
def resolve_all_target_account_reports
|
||||||
unresolved_reports_for_target_account.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
|
unresolved_reports_for_target_account.update_all(
|
||||||
|
action_taken_by_current_attributes
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def unresolved_reports_for_target_account
|
def unresolved_reports_for_target_account
|
||||||
|
|||||||
@@ -2,19 +2,17 @@
|
|||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class ResetsController < BaseController
|
class ResetsController < BaseController
|
||||||
before_action :set_user
|
before_action :set_account
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @user, :reset_password?
|
@account.user.send_reset_password_instructions
|
||||||
@user.send_reset_password_instructions
|
|
||||||
log_action :reset_password, @user
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_user
|
def set_account
|
||||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
@account = Account.find(params[:account_id])
|
||||||
end
|
end
|
||||||
end
|
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,48 +13,24 @@ module Admin
|
|||||||
closed_registrations_message
|
closed_registrations_message
|
||||||
open_deletion
|
open_deletion
|
||||||
timeline_preview
|
timeline_preview
|
||||||
show_staff_badge
|
|
||||||
bootstrap_timeline_accounts
|
bootstrap_timeline_accounts
|
||||||
thumbnail
|
|
||||||
hero
|
|
||||||
min_invite_role
|
|
||||||
activity_api_enabled
|
|
||||||
peers_api_enabled
|
|
||||||
show_known_fediverse_at_about_page
|
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
BOOLEAN_SETTINGS = %w(
|
BOOLEAN_SETTINGS = %w(
|
||||||
open_registrations
|
open_registrations
|
||||||
open_deletion
|
open_deletion
|
||||||
timeline_preview
|
timeline_preview
|
||||||
show_staff_badge
|
|
||||||
activity_api_enabled
|
|
||||||
peers_api_enabled
|
|
||||||
show_known_fediverse_at_about_page
|
|
||||||
).freeze
|
|
||||||
|
|
||||||
UPLOAD_SETTINGS = %w(
|
|
||||||
thumbnail
|
|
||||||
hero
|
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
authorize :settings, :show?
|
|
||||||
@admin_settings = Form::AdminSettings.new
|
@admin_settings = Form::AdminSettings.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize :settings, :update?
|
|
||||||
|
|
||||||
settings_params.each do |key, value|
|
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 = Setting.where(var: key).first_or_initialize(var: key)
|
||||||
setting.update(value: value_for_update(key, value))
|
setting.update(value: value_for_update(key, value))
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
||||||
redirect_to edit_admin_settings_path
|
redirect_to edit_admin_settings_path
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ module Admin
|
|||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @account, :silence?
|
@account.update(silenced: true)
|
||||||
@account.update!(silenced: true)
|
|
||||||
log_action :silence, @account
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @account, :unsilence?
|
@account.update(silenced: false)
|
||||||
@account.update!(silenced: false)
|
|
||||||
log_action :unsilence, @account
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
module Admin
|
module Admin
|
||||||
class StatusesController < BaseController
|
class StatusesController < BaseController
|
||||||
|
include Authorization
|
||||||
|
|
||||||
helper_method :current_params
|
helper_method :current_params
|
||||||
|
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
@@ -10,39 +12,31 @@ module Admin
|
|||||||
PER_PAGE = 20
|
PER_PAGE = 20
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :status, :index?
|
@statuses = @account.statuses
|
||||||
|
|
||||||
@statuses = @account.statuses.where(visibility: [:public, :unlisted])
|
|
||||||
|
|
||||||
if params[:media]
|
if params[:media]
|
||||||
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).distinct
|
account_media_status_ids = @account.media_attachments.attached.reorder(nil).select(:status_id).distinct
|
||||||
@statuses.merge!(Status.where(id: account_media_status_ids))
|
@statuses.merge!(Status.where(id: account_media_status_ids))
|
||||||
end
|
end
|
||||||
|
|
||||||
@statuses = @statuses.preload(:media_attachments, :mentions).page(params[:page]).per(PER_PAGE)
|
@statuses = @statuses.preload(:media_attachments, :mentions).page(params[:page]).per(PER_PAGE)
|
||||||
|
|
||||||
@form = Form::StatusBatch.new
|
@form = Form::StatusBatch.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize :status, :update?
|
@form = Form::StatusBatch.new(form_status_batch_params)
|
||||||
|
flash[:alert] = t('admin.statuses.failed_to_execute') unless @form.save
|
||||||
@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
|
|
||||||
|
|
||||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize @status, :update?
|
@status.update(status_params)
|
||||||
@status.update!(status_params)
|
|
||||||
log_action :update, @status
|
|
||||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @status, :destroy?
|
authorize @status, :destroy?
|
||||||
RemovalWorker.perform_async(@status.id)
|
RemovalWorker.perform_async(@status.id)
|
||||||
log_action :destroy, @status
|
|
||||||
render json: @status
|
render json: @status
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -66,7 +60,6 @@ module Admin
|
|||||||
|
|
||||||
def current_params
|
def current_params
|
||||||
page = (params[:page] || 1).to_i
|
page = (params[:page] || 1).to_i
|
||||||
|
|
||||||
{
|
{
|
||||||
media: params[:media],
|
media: params[:media],
|
||||||
page: page > 1 && page,
|
page: page > 1 && page,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
module Admin
|
module Admin
|
||||||
class SubscriptionsController < BaseController
|
class SubscriptionsController < BaseController
|
||||||
def index
|
def index
|
||||||
authorize :subscription, :index?
|
|
||||||
@subscriptions = ordered_subscriptions.page(requested_page)
|
@subscriptions = ordered_subscriptions.page(requested_page)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,12 @@ module Admin
|
|||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @account, :suspend?
|
|
||||||
Admin::SuspensionWorker.perform_async(@account.id)
|
Admin::SuspensionWorker.perform_async(@account.id)
|
||||||
log_action :suspend, @account
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @account, :unsuspend?
|
@account.update(suspended: false)
|
||||||
@account.unsuspend!
|
|
||||||
log_action :unsuspend, @account
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ module Admin
|
|||||||
before_action :set_user
|
before_action :set_user
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
authorize @user, :disable_2fa?
|
|
||||||
@user.disable_two_factor!
|
@user.disable_two_factor!
|
||||||
log_action :disable_2fa, @user
|
|
||||||
redirect_to admin_accounts_path
|
redirect_to admin_accounts_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ class Api::BaseController < ApplicationController
|
|||||||
|
|
||||||
include RateLimitHeaders
|
include RateLimitHeaders
|
||||||
|
|
||||||
|
skip_before_action :verify_authenticity_token
|
||||||
skip_before_action :store_current_location
|
skip_before_action :store_current_location
|
||||||
protect_from_forgery with: :null_session
|
|
||||||
|
|
||||||
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
||||||
render json: { error: e.to_s }, status: 422
|
render json: { error: e.to_s }, status: 422
|
||||||
@@ -51,10 +51,6 @@ class Api::BaseController < ApplicationController
|
|||||||
[params[:limit].to_i.abs, default_limit * 2].min
|
[params[:limit].to_i.abs, default_limit * 2].min
|
||||||
end
|
end
|
||||||
|
|
||||||
def truthy_param?(key)
|
|
||||||
ActiveModel::Type::Boolean.new.cast(params[key])
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_resource_owner
|
def current_resource_owner
|
||||||
@current_user ||= User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
@current_user ||= User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
||||||
end
|
end
|
||||||
@@ -76,4 +72,19 @@ class Api::BaseController < ApplicationController
|
|||||||
def render_empty
|
def render_empty
|
||||||
render json: {}, status: 200
|
render json: {}, status: 200
|
||||||
end
|
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
|
end
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::SalmonController < Api::BaseController
|
class Api::SalmonController < Api::BaseController
|
||||||
include SignatureVerification
|
|
||||||
|
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
respond_to :txt
|
respond_to :txt
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if verify_payload?
|
if verify_payload?
|
||||||
process_salmon
|
process_salmon
|
||||||
head 202
|
head 201
|
||||||
elsif payload.present?
|
|
||||||
render plain: signature_verification_failure_reason, status: 401
|
|
||||||
else
|
else
|
||||||
head 400
|
head 202
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
|||||||
def update
|
def update
|
||||||
@account = current_account
|
@account = current_account
|
||||||
UpdateAccountService.new.call(@account, account_params, raise_error: true)
|
UpdateAccountService.new.call(@account, account_params, raise_error: true)
|
||||||
UserSettingsDecorator.new(current_user).update(user_settings_params) if user_settings_params
|
|
||||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||||
render json: @account, serializer: REST::CredentialAccountSerializer
|
render json: @account, serializer: REST::CredentialAccountSerializer
|
||||||
end
|
end
|
||||||
@@ -21,17 +20,6 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def account_params
|
def account_params
|
||||||
params.permit(:display_name, :note, :avatar, :header, :locked)
|
params.permit(:display_name, :note, :avatar, :header)
|
||||||
end
|
|
||||||
|
|
||||||
def user_settings_params
|
|
||||||
return nil unless params.key?(:source)
|
|
||||||
|
|
||||||
source_params = params.require(:source)
|
|
||||||
|
|
||||||
{
|
|
||||||
'setting_default_privacy' => source_params.fetch(:privacy, @account.user.setting_default_privacy),
|
|
||||||
'setting_default_sensitive' => source_params.fetch(:sensitive, @account.user.setting_default_sensitive),
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -63,6 +63,6 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -63,6 +63,6 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
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
|
respond_to :json
|
||||||
|
|
||||||
def index
|
def index
|
||||||
accounts = Account.where(id: account_ids).select('id')
|
@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).compact
|
|
||||||
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
|
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -21,6 +18,6 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def account_ids
|
def account_ids
|
||||||
Array(params[:id]).map(&:to_i)
|
@_account_ids ||= Array(params[:id]).map(&:to_i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ class Api::V1::Accounts::SearchController < Api::BaseController
|
|||||||
AccountSearchService.new.call(
|
AccountSearchService.new.call(
|
||||||
params[:q],
|
params[:q],
|
||||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||||
current_account,
|
resolving_search?,
|
||||||
resolve: truthy_param?(:resolve),
|
current_account
|
||||||
following: truthy_param?(:following)
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def resolving_search?
|
||||||
|
params[:resolve] == 'true'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
|||||||
|
|
||||||
def account_statuses
|
def account_statuses
|
||||||
default_statuses.tap do |statuses|
|
default_statuses.tap do |statuses|
|
||||||
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
|
statuses.merge!(only_media_scope) if params[:only_media]
|
||||||
statuses.merge!(pinned_scope) if truthy_param?(:pinned)
|
statuses.merge!(pinned_scope) if params[:pinned]
|
||||||
statuses.merge!(no_replies_scope) if truthy_param?(:exclude_replies)
|
statuses.merge!(no_replies_scope) if params[:exclude_replies]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -51,13 +51,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def account_media_status_ids
|
def account_media_status_ids
|
||||||
# `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
|
@account.media_attachments.attached.reorder(nil).select(:status_id).distinct
|
||||||
# Also, Avoid getting slow by not narrowing down by `statuses.account_id`.
|
|
||||||
# When narrowing down by `statuses.account_id`, `index_statuses_20180106` will be used
|
|
||||||
# and the table will be joined by `Merge Semi Join`, so the query will be slow.
|
|
||||||
Status.joins(:media_attachments).merge(@account.media_attachments).permitted_for(@account, current_account)
|
|
||||||
.paginate_by_max_id(limit_param(DEFAULT_STATUSES_LIMIT), params[:max_id], params[:since_id])
|
|
||||||
.reorder(id: :desc).distinct(:id).pluck(:id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def pinned_scope
|
def pinned_scope
|
||||||
@@ -69,7 +63,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
params.permit(:limit, :only_media, :exclude_replies).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ class Api::V1::AccountsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def follow
|
def follow
|
||||||
FollowService.new.call(current_user.account, @account.acct, reblogs: truthy_param?(:reblogs))
|
FollowService.new.call(current_user.account, @account.acct)
|
||||||
|
|
||||||
options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } }
|
options = @account.locked? ? {} : { following_map: { @account.id => true }, requested_map: { @account.id => false } }
|
||||||
|
|
||||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
|
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
|
||||||
end
|
end
|
||||||
@@ -26,7 +26,7 @@ class Api::V1::AccountsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def mute
|
def mute
|
||||||
MuteService.new.call(current_user.account, @account, notifications: truthy_param?(:notifications))
|
MuteService.new.call(current_user.account, @account, notifications: params[:notifications])
|
||||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class Api::V1::AccountsController < Api::BaseController
|
|||||||
@account = Account.find(params[:id])
|
@account = Account.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships(**options)
|
def relationships(options = {})
|
||||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
|
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, options)
|
||||||
end
|
end
|
||||||
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::AppsController < Api::BaseController
|
class Api::V1::AppsController < Api::BaseController
|
||||||
|
respond_to :json
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@app = Doorkeeper::Application.create!(application_options)
|
@app = Doorkeeper::Application.create!(application_options)
|
||||||
render json: @app, serializer: REST::ApplicationSerializer
|
render json: @app, serializer: REST::ApplicationSerializer
|
||||||
|
|||||||
@@ -15,13 +15,15 @@ class Api::V1::BlocksController < Api::BaseController
|
|||||||
private
|
private
|
||||||
|
|
||||||
def load_accounts
|
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
|
end
|
||||||
|
|
||||||
def paginated_blocks
|
def paginated_blocks
|
||||||
@paginated_blocks ||= Block.eager_load(:target_account)
|
Block.where(account: current_account).paginate_by_max_id(
|
||||||
.where(account: current_account)
|
|
||||||
.paginate_by_max_id(
|
|
||||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||||
params[:max_id],
|
params[:max_id],
|
||||||
params[:since_id]
|
params[:since_id]
|
||||||
@@ -39,24 +41,24 @@ class Api::V1::BlocksController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
unless paginated_blocks.empty?
|
unless @accounts.empty?
|
||||||
api_v1_blocks_url pagination_params(since_id: pagination_since_id)
|
api_v1_blocks_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_max_id
|
def pagination_max_id
|
||||||
paginated_blocks.last.id
|
@accounts.last.blocked_by_ids.last
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_since_id
|
def pagination_since_id
|
||||||
paginated_blocks.first.id
|
@accounts.first.blocked_by_ids.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def records_continue?
|
def records_continue?
|
||||||
paginated_blocks.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::BookmarksController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :read }
|
|
||||||
before_action :require_user!
|
|
||||||
after_action :insert_pagination_headers
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def index
|
|
||||||
@statuses = load_statuses
|
|
||||||
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def load_statuses
|
|
||||||
cached_bookmarks
|
|
||||||
end
|
|
||||||
|
|
||||||
def cached_bookmarks
|
|
||||||
cache_collection(
|
|
||||||
Status.reorder(nil).joins(:bookmarks).merge(results),
|
|
||||||
Status
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def results
|
|
||||||
@_results ||= account_bookmarks.paginate_by_max_id(
|
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
|
||||||
params[:max_id],
|
|
||||||
params[:since_id]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_bookmarks
|
|
||||||
current_account.bookmarks
|
|
||||||
end
|
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
|
||||||
if records_continue?
|
|
||||||
api_v1_bookmarks_url pagination_params(max_id: pagination_max_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def prev_path
|
|
||||||
unless results.empty?
|
|
||||||
api_v1_bookmarks_url pagination_params(since_id: pagination_since_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_max_id
|
|
||||||
results.last.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_since_id
|
|
||||||
results.first.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def records_continue?
|
|
||||||
results.size == limit_param(DEFAULT_STATUSES_LIMIT)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -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
|
|
||||||
@@ -67,7 +67,7 @@ class Api::V1::DomainBlocksController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_block_params
|
def domain_block_params
|
||||||
|
|||||||
8
app/controllers/api/v1/extensions_controller.rb
Normal file
8
app/controllers/api/v1/extensions_controller.rb
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
require 'mastodon/extension'
|
||||||
|
|
||||||
|
class Api::V1::ExtensionsController < Api::BaseController
|
||||||
|
def index
|
||||||
|
render json: Mastodon::Extension.all
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -66,6 +66,6 @@ class Api::V1::FavouritesController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -71,6 +71,6 @@ class Api::V1::FollowRequestsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Instances::ActivityController < Api::BaseController
|
|
||||||
before_action :require_enabled_api!
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def show
|
|
||||||
render_cached_json('api:v1:instances:activity:show', expires_in: 1.day) { activity }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def activity
|
|
||||||
weeks = []
|
|
||||||
|
|
||||||
12.times do |i|
|
|
||||||
day = i.weeks.ago.to_date
|
|
||||||
week_id = day.cweek
|
|
||||||
week = Date.commercial(day.cwyear, week_id)
|
|
||||||
|
|
||||||
weeks << {
|
|
||||||
week: week.to_time.to_i.to_s,
|
|
||||||
statuses: Redis.current.get("activity:statuses:local:#{week_id}") || '0',
|
|
||||||
logins: Redis.current.pfcount("activity:logins:#{week_id}").to_s,
|
|
||||||
registrations: Redis.current.get("activity:accounts:local:#{week_id}") || '0',
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
weeks
|
|
||||||
end
|
|
||||||
|
|
||||||
def require_enabled_api!
|
|
||||||
head 404 unless Setting.activity_api_enabled
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Instances::PeersController < Api::BaseController
|
|
||||||
before_action :require_enabled_api!
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def index
|
|
||||||
render_cached_json('api:v1:instances:peers:index', expires_in: 1.day) { Account.remote.domains }
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def require_enabled_api!
|
|
||||||
head 404 unless Setting.peers_api_enabled
|
|
||||||
end
|
|
||||||
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.slice(:limit).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
|
respond_to :json
|
||||||
|
|
||||||
def create
|
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
|
render json: @media, serializer: REST::MediaAttachmentSerializer
|
||||||
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
|
rescue Paperclip::Errors::NotIdentifiedByImageMagickError
|
||||||
render json: file_type_error, status: 422
|
render json: file_type_error, status: 422
|
||||||
@@ -18,16 +18,10 @@ class Api::V1::MediaController < Api::BaseController
|
|||||||
render json: processing_error, status: 500
|
render json: processing_error, status: 500
|
||||||
end
|
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
|
private
|
||||||
|
|
||||||
def media_params
|
def media_params
|
||||||
params.permit(:file, :description, :focus)
|
params.permit(:file)
|
||||||
end
|
end
|
||||||
|
|
||||||
def file_type_error
|
def file_type_error
|
||||||
|
|||||||
@@ -76,6 +76,6 @@ class Api::V1::MutesController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -91,6 +91,6 @@ class Api::V1::NotificationsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit, :exclude_types).permit(:limit, exclude_types: []).merge(core_params)
|
params.permit(:limit, exclude_types: []).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ class Api::V1::ReportsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@report = ReportService.new.call(
|
@report = current_account.reports.create!(
|
||||||
current_account,
|
target_account: reported_account,
|
||||||
reported_account,
|
|
||||||
status_ids: reported_status_ids,
|
status_ids: reported_status_ids,
|
||||||
comment: report_params[:comment],
|
comment: report_params[:comment]
|
||||||
forward: report_params[:forward]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
User.admins.includes(:account).each { |u| AdminMailer.new_report(u.account, @report).deliver_later }
|
||||||
|
|
||||||
render json: @report, serializer: REST::ReportSerializer
|
render json: @report, serializer: REST::ReportSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -39,6 +39,6 @@ class Api::V1::ReportsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def report_params
|
def report_params
|
||||||
params.permit(:account_id, :comment, :forward, status_ids: [])
|
params.permit(:account_id, :comment, status_ids: [])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::SearchController < Api::BaseController
|
class Api::V1::SearchController < Api::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
RESULTS_LIMIT = 10
|
RESULTS_LIMIT = 10
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :read }
|
before_action -> { doorkeeper_authorize! :read }
|
||||||
@@ -11,30 +9,22 @@ class Api::V1::SearchController < Api::BaseController
|
|||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@search = Search.new(search)
|
@search = Search.new(search_results)
|
||||||
render json: @search, serializer: REST::SearchSerializer
|
render json: @search, serializer: REST::SearchSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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
|
def search_results
|
||||||
SearchService.new.call(
|
SearchService.new.call(
|
||||||
params[:q],
|
params[:q],
|
||||||
RESULTS_LIMIT,
|
RESULTS_LIMIT,
|
||||||
truthy_param?(:resolve),
|
resolving_search?,
|
||||||
current_account
|
current_account
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def resolving_search?
|
||||||
|
params[:resolve] == 'true'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Statuses::BookmarksController < Api::BaseController
|
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write }
|
|
||||||
before_action :require_user!
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def create
|
|
||||||
@status = bookmarked_status
|
|
||||||
render json: @status, serializer: REST::StatusSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@status = requested_status
|
|
||||||
@bookmarks_map = { @status.id => false }
|
|
||||||
|
|
||||||
bookmark = Bookmark.find_by!(account: current_user.account, status: @status)
|
|
||||||
bookmark.destroy!
|
|
||||||
|
|
||||||
render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_user&.account_id, bookmarks_map: @bookmarks_map)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def bookmarked_status
|
|
||||||
authorize_with current_user.account, requested_status, :show?
|
|
||||||
|
|
||||||
bookmark = Bookmark.find_or_create_by!(account: current_user.account, status: requested_status)
|
|
||||||
|
|
||||||
bookmark.status.reload
|
|
||||||
end
|
|
||||||
|
|
||||||
def requested_status
|
|
||||||
Status.find(params[:status_id])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -77,6 +77,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,18 +11,12 @@ class Api::V1::Statuses::PinsController < Api::BaseController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
StatusPin.create!(account: current_account, status: @status)
|
StatusPin.create!(account: current_account, status: @status)
|
||||||
distribute_add_activity!
|
|
||||||
render json: @status, serializer: REST::StatusSerializer
|
render json: @status, serializer: REST::StatusSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
pin = StatusPin.find_by(account: current_account, status: @status)
|
pin = StatusPin.find_by(account: current_account, status: @status)
|
||||||
|
pin&.destroy!
|
||||||
if pin
|
|
||||||
pin.destroy!
|
|
||||||
distribute_remove_activity!
|
|
||||||
end
|
|
||||||
|
|
||||||
render json: @status, serializer: REST::StatusSerializer
|
render json: @status, serializer: REST::StatusSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -31,24 +25,4 @@ class Api::V1::Statuses::PinsController < Api::BaseController
|
|||||||
def set_status
|
def set_status
|
||||||
@status = Status.find(params[:status_id])
|
@status = Status.find(params[:status_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def distribute_add_activity!
|
|
||||||
json = ActiveModelSerializers::SerializableResource.new(
|
|
||||||
@status,
|
|
||||||
serializer: ActivityPub::AddSerializer,
|
|
||||||
adapter: ActivityPub::Adapter
|
|
||||||
).as_json
|
|
||||||
|
|
||||||
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account)
|
|
||||||
end
|
|
||||||
|
|
||||||
def distribute_remove_activity!
|
|
||||||
json = ActiveModelSerializers::SerializableResource.new(
|
|
||||||
@status,
|
|
||||||
serializer: ActivityPub::RemoveSerializer,
|
|
||||||
adapter: ActivityPub::Adapter
|
|
||||||
).as_json
|
|
||||||
|
|
||||||
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -74,6 +74,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Api::V1::StatusesController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def context
|
def context
|
||||||
ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(DEFAULT_STATUSES_LIMIT, current_account)
|
ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(current_account)
|
||||||
descendants_results = @status.descendants(current_account)
|
descendants_results = @status.descendants(current_account)
|
||||||
loaded_ancestors = cache_collection(ancestors_results, Status)
|
loaded_ancestors = cache_collection(ancestors_results, Status)
|
||||||
loaded_descendants = cache_collection(descendants_results, Status)
|
loaded_descendants = cache_collection(descendants_results, Status)
|
||||||
@@ -76,7 +76,7 @@ class Api::V1::StatusesController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def authorize_if_got_token
|
def authorize_if_got_token
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -9,11 +9,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
|||||||
|
|
||||||
def show
|
def show
|
||||||
@statuses = load_statuses
|
@statuses = load_statuses
|
||||||
|
render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id)
|
||||||
render json: @statuses,
|
|
||||||
each_serializer: REST::StatusSerializer,
|
|
||||||
relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id),
|
|
||||||
status: regeneration_in_progress? ? 206 : 200
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -35,7 +31,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def account_home_feed
|
def account_home_feed
|
||||||
HomeFeed.new(current_account)
|
Feed.new(:home, current_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
@@ -43,7 +39,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:local, :limit).permit(:local, :limit).merge(core_params)
|
params.permit(:local, :limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
@@ -61,8 +57,4 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
|||||||
def pagination_since_id
|
def pagination_since_id
|
||||||
@statuses.first.id
|
@statuses.first.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def regeneration_in_progress?
|
|
||||||
Redis.current.exists("account:#{current_account.id}:regeneration")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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.slice(:limit).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
|
|
||||||
@@ -21,23 +21,15 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def public_statuses
|
def public_statuses
|
||||||
statuses = public_timeline_statuses.paginate_by_max_id(
|
public_timeline_statuses.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params[:max_id],
|
params[:max_id],
|
||||||
params[:since_id]
|
params[:since_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
if truthy_param?(:only_media)
|
|
||||||
# `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
|
|
||||||
status_ids = statuses.joins(:media_attachments).distinct(:id).pluck(:id)
|
|
||||||
statuses.where(id: status_ids)
|
|
||||||
else
|
|
||||||
statuses
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_timeline_statuses
|
def public_timeline_statuses
|
||||||
Status.as_public_timeline(current_account, truthy_param?(:local))
|
Status.as_public_timeline(current_account, params[:local])
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
@@ -45,7 +37,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
|
params.permit(:local, :limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
|
|||||||
@@ -29,24 +29,16 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
|||||||
if @tag.nil?
|
if @tag.nil?
|
||||||
[]
|
[]
|
||||||
else
|
else
|
||||||
statuses = tag_timeline_statuses.paginate_by_max_id(
|
tag_timeline_statuses.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params[:max_id],
|
params[:max_id],
|
||||||
params[:since_id]
|
params[:since_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
if truthy_param?(:only_media)
|
|
||||||
# `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids.
|
|
||||||
status_ids = statuses.joins(:media_attachments).distinct(:id).pluck(:id)
|
|
||||||
statuses.where(id: status_ids)
|
|
||||||
else
|
|
||||||
statuses
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_timeline_statuses
|
def tag_timeline_statuses
|
||||||
Status.as_tag_timeline(@tag, current_account, truthy_param?(:local))
|
Status.as_tag_timeline(@tag, current_account, params[:local])
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
@@ -54,7 +46,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
|
params.permit(:local, :limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::Web::BaseController < Api::BaseController
|
|
||||||
protect_from_forgery with: :exception
|
|
||||||
|
|
||||||
rescue_from ActionController::InvalidAuthenticityToken do
|
|
||||||
render json: { error: "Can't verify CSRF token authenticity." }, status: 422
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::Web::EmbedsController < Api::Web::BaseController
|
class Api::Web::EmbedsController < Api::BaseController
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
class Api::Web::PushSubscriptionsController < Api::BaseController
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
params.require(:subscription).require(:endpoint)
|
||||||
|
params.require(:subscription).require(:keys).require([:auth, :p256dh])
|
||||||
|
|
||||||
active_session = current_session
|
active_session = current_session
|
||||||
|
|
||||||
unless active_session.web_push_subscription.nil?
|
unless active_session.web_push_subscription.nil?
|
||||||
@@ -25,12 +28,10 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
data.deep_merge!(data_params) if params[:data]
|
|
||||||
|
|
||||||
web_subscription = ::Web::PushSubscription.create!(
|
web_subscription = ::Web::PushSubscription.create!(
|
||||||
endpoint: subscription_params[:endpoint],
|
endpoint: params[:subscription][:endpoint],
|
||||||
key_p256dh: subscription_params[:keys][:p256dh],
|
key_p256dh: params[:subscription][:keys][:p256dh],
|
||||||
key_auth: subscription_params[:keys][:auth],
|
key_auth: params[:subscription][:keys][:auth],
|
||||||
data: data
|
data: data
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,22 +41,12 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
params.require([:id])
|
params.require([:id, :data])
|
||||||
|
|
||||||
web_subscription = ::Web::PushSubscription.find(params[:id])
|
web_subscription = ::Web::PushSubscription.find(params[:id])
|
||||||
|
|
||||||
web_subscription.update!(data: data_params)
|
web_subscription.update!(data: params[:data])
|
||||||
|
|
||||||
render json: web_subscription.as_payload
|
render json: web_subscription.as_payload
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def subscription_params
|
|
||||||
@subscription_params ||= params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
|
|
||||||
end
|
|
||||||
|
|
||||||
def data_params
|
|
||||||
@data_params ||= params.require(:data).permit(:alerts)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::Web::SettingsController < Api::Web::BaseController
|
class Api::Web::SettingsController < Api::BaseController
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|||||||
@@ -12,15 +12,11 @@ class ApplicationController < ActionController::Base
|
|||||||
|
|
||||||
helper_method :current_account
|
helper_method :current_account
|
||||||
helper_method :current_session
|
helper_method :current_session
|
||||||
helper_method :current_flavour
|
|
||||||
helper_method :current_skin
|
|
||||||
helper_method :single_user_mode?
|
helper_method :single_user_mode?
|
||||||
helper_method :use_seamless_external_login?
|
|
||||||
|
|
||||||
rescue_from ActionController::RoutingError, with: :not_found
|
rescue_from ActionController::RoutingError, with: :not_found
|
||||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||||
rescue_from ActionController::InvalidAuthenticityToken, with: :unprocessable_entity
|
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 :store_current_location, except: :raise_not_found, unless: :devise_controller?
|
||||||
before_action :check_suspension, if: :user_signed_in?
|
before_action :check_suspension, if: :user_signed_in?
|
||||||
@@ -32,19 +28,15 @@ class ApplicationController < ActionController::Base
|
|||||||
private
|
private
|
||||||
|
|
||||||
def https_enabled?
|
def https_enabled?
|
||||||
Rails.env.production?
|
Rails.env.production? && ENV['LOCAL_HTTPS'] == 'true'
|
||||||
end
|
end
|
||||||
|
|
||||||
def store_current_location
|
def store_current_location
|
||||||
store_location_for(:user, request.url) unless request.format == :json
|
store_location_for(:user, request.url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_admin!
|
def require_admin!
|
||||||
forbidden unless current_user&.admin?
|
redirect_to root_path unless current_user&.admin?
|
||||||
end
|
|
||||||
|
|
||||||
def require_staff!
|
|
||||||
forbidden unless current_user&.staff?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_suspension
|
def check_suspension
|
||||||
@@ -55,75 +47,6 @@ class ApplicationController < ActionController::Base
|
|||||||
new_user_session_path
|
new_user_session_path
|
||||||
end
|
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
|
protected
|
||||||
|
|
||||||
def forbidden
|
def forbidden
|
||||||
@@ -146,10 +69,6 @@ class ApplicationController < ActionController::Base
|
|||||||
@single_user_mode ||= Rails.configuration.x.single_user_mode && Account.exists?
|
@single_user_mode ||= Rails.configuration.x.single_user_mode && Account.exists?
|
||||||
end
|
end
|
||||||
|
|
||||||
def use_seamless_external_login?
|
|
||||||
Devise.pam_authentication || Devise.ldap_authentication
|
|
||||||
end
|
|
||||||
|
|
||||||
def current_account
|
def current_account
|
||||||
@current_account ||= current_user.try(:account)
|
@current_account ||= current_user.try(:account)
|
||||||
end
|
end
|
||||||
@@ -158,16 +77,6 @@ class ApplicationController < ActionController::Base
|
|||||||
@current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id'])
|
@current_session ||= SessionActivation.find_by(session_id: cookies.signed['_session_id'])
|
||||||
end
|
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)
|
def cache_collection(raw, klass)
|
||||||
return raw unless klass.respond_to?(:with_includes)
|
return raw unless klass.respond_to?(:with_includes)
|
||||||
|
|
||||||
@@ -184,7 +93,7 @@ class ApplicationController < ActionController::Base
|
|||||||
unless uncached_ids.empty?
|
unless uncached_ids.empty?
|
||||||
uncached = klass.where(id: uncached_ids).with_includes.map { |item| [item.id, item] }.to_h
|
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)
|
Rails.cache.write(item.cache_key, item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -197,31 +106,8 @@ class ApplicationController < ActionController::Base
|
|||||||
format.any { head code }
|
format.any { head code }
|
||||||
format.html do
|
format.html do
|
||||||
set_locale
|
set_locale
|
||||||
use_pack 'error'
|
|
||||||
render "errors/#{code}", layout: 'error', status: code
|
render "errors/#{code}", layout: 'error', status: code
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_cached_json(cache_key, **options)
|
|
||||||
options[:expires_in] ||= 3.minutes
|
|
||||||
cache_key = cache_key.join(':') if cache_key.is_a?(Enumerable)
|
|
||||||
cache_public = options.key?(:public) ? options.delete(:public) : true
|
|
||||||
content_type = options.delete(:content_type) || 'application/json'
|
|
||||||
|
|
||||||
data = Rails.cache.fetch(cache_key, { raw: true }.merge(options)) do
|
|
||||||
yield.to_json
|
|
||||||
end
|
|
||||||
|
|
||||||
expires_in options[:expires_in], public: cache_public
|
|
||||||
render json: data, content_type: content_type
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_cache_headers
|
|
||||||
response.headers['Vary'] = 'Accept'
|
|
||||||
end
|
|
||||||
|
|
||||||
def skip_session!
|
|
||||||
request.session_options[:skip] = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -3,34 +3,9 @@
|
|||||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
before_action :set_user, only: [:finish_signup]
|
def show
|
||||||
before_action :set_pack
|
super do |user|
|
||||||
|
BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty?
|
||||||
private
|
|
||||||
|
|
||||||
def set_pack
|
|
||||||
use_pack 'auth'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET/PATCH /users/:id/finish_signup
|
|
||||||
def finish_signup
|
|
||||||
return unless request.patch? && params[:user]
|
|
||||||
if @user.update(user_params)
|
|
||||||
@user.skip_reconfirmation!
|
|
||||||
sign_in(@user, bypass: true)
|
|
||||||
redirect_to root_path, notice: I18n.t('devise.confirmations.send_instructions')
|
|
||||||
else
|
|
||||||
@show_errors = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_user
|
|
||||||
@user = current_user
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_params
|
|
||||||
params.require(:user).permit(:email)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|
||||||
skip_before_action :verify_authenticity_token
|
|
||||||
|
|
||||||
def self.provides_callback_for(provider)
|
|
||||||
provider_id = provider.to_s.chomp '_oauth2'
|
|
||||||
|
|
||||||
define_method provider do
|
|
||||||
@user = User.find_for_oauth(request.env['omniauth.auth'], current_user)
|
|
||||||
|
|
||||||
if @user.persisted?
|
|
||||||
sign_in_and_redirect @user, event: :authentication
|
|
||||||
set_flash_message(:notice, :success, kind: provider_id.capitalize) if is_navigational_format?
|
|
||||||
else
|
|
||||||
session["devise.#{provider}_data"] = request.env['omniauth.auth']
|
|
||||||
redirect_to new_user_registration_url
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Devise.omniauth_configs.each_key do |provider|
|
|
||||||
provides_callback_for provider
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_sign_in_path_for(resource)
|
|
||||||
if resource.email_verified?
|
|
||||||
root_path
|
|
||||||
else
|
|
||||||
finish_signup_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
class Auth::PasswordsController < Devise::PasswordsController
|
class Auth::PasswordsController < Devise::PasswordsController
|
||||||
before_action :check_validity_of_reset_password_token, only: :edit
|
before_action :check_validity_of_reset_password_token, only: :edit
|
||||||
before_action :set_pack
|
|
||||||
|
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
@@ -18,8 +17,4 @@ class Auth::PasswordsController < Devise::PasswordsController
|
|||||||
def reset_password_token_is_valid?
|
def reset_password_token_is_valid?
|
||||||
resource_class.with_reset_password_token(params[:reset_password_token]).present?
|
resource_class.with_reset_password_token(params[:reset_password_token]).present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_pack
|
|
||||||
use_pack 'auth'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||||||
|
|
||||||
before_action :check_enabled_registrations, only: [:new, :create]
|
before_action :check_enabled_registrations, only: [:new, :create]
|
||||||
before_action :configure_sign_up_params, only: [:create]
|
before_action :configure_sign_up_params, only: [:create]
|
||||||
before_action :set_pack
|
|
||||||
before_action :set_sessions, only: [:edit, :update]
|
before_action :set_sessions, only: [:edit, :update]
|
||||||
before_action :set_instance_presenter, only: [:new, :create, :update]
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
not_found
|
not_found
|
||||||
@@ -15,23 +13,15 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def update_resource(resource, params)
|
|
||||||
params[:password] = nil if Devise.pam_authentication && resource.encrypted_password.blank?
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_resource(hash = nil)
|
def build_resource(hash = nil)
|
||||||
super(hash)
|
super(hash)
|
||||||
|
|
||||||
resource.locale = I18n.locale
|
resource.locale = I18n.locale
|
||||||
resource.invite_code = params[:invite_code] if resource.invite_code.blank?
|
|
||||||
|
|
||||||
resource.build_account if resource.account.nil?
|
resource.build_account if resource.account.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure_sign_up_params
|
def configure_sign_up_params
|
||||||
devise_parameter_sanitizer.permit(:sign_up) do |u|
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -43,36 +33,12 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||||||
new_user_session_path
|
new_user_session_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_update_path_for(_resource)
|
|
||||||
edit_user_registration_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_enabled_registrations
|
def check_enabled_registrations
|
||||||
redirect_to root_path if single_user_mode? || !allowed_registrations?
|
redirect_to root_path if single_user_mode? || !Setting.open_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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
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
|
def determine_layout
|
||||||
%w(edit update).include?(action_name) ? 'admin' : 'auth'
|
%w(edit update).include?(action_name) ? 'admin' : 'auth'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,16 +8,6 @@ class Auth::SessionsController < Devise::SessionsController
|
|||||||
skip_before_action :require_no_authentication, only: [:create]
|
skip_before_action :require_no_authentication, only: [:create]
|
||||||
skip_before_action :check_suspension, only: [:destroy]
|
skip_before_action :check_suspension, only: [:destroy]
|
||||||
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
|
||||||
prepend_before_action :set_pack
|
|
||||||
before_action :set_instance_presenter, only: [:new]
|
|
||||||
|
|
||||||
def new
|
|
||||||
Devise.omniauth_configs.each do |provider, config|
|
|
||||||
return redirect_to(omniauth_authorize_path(resource_name, provider)) if config.strategy.redirect_at_sign_in
|
|
||||||
end
|
|
||||||
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
super do |resource|
|
super do |resource|
|
||||||
@@ -37,13 +27,9 @@ class Auth::SessionsController < Devise::SessionsController
|
|||||||
if session[:otp_user_id]
|
if session[:otp_user_id]
|
||||||
User.find(session[:otp_user_id])
|
User.find(session[:otp_user_id])
|
||||||
elsif user_params[:email]
|
elsif user_params[:email]
|
||||||
if use_seamless_external_login? && Devise.check_at_sign && user_params[:email].index('@').nil?
|
|
||||||
User.joins(:account).find_by(accounts: { username: user_params[:email] })
|
|
||||||
else
|
|
||||||
User.find_for_authentication(email: user_params[:email])
|
User.find_for_authentication(email: user_params[:email])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
params.require(:user).permit(:email, :password, :otp_attempt)
|
params.require(:user).permit(:email, :password, :otp_attempt)
|
||||||
@@ -59,14 +45,6 @@ class Auth::SessionsController < Devise::SessionsController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_sign_out_path_for(_resource_or_scope)
|
|
||||||
Devise.omniauth_configs.each_value do |config|
|
|
||||||
return root_path if config.strategy.redirect_at_sign_in
|
|
||||||
end
|
|
||||||
|
|
||||||
super
|
|
||||||
end
|
|
||||||
|
|
||||||
def two_factor_enabled?
|
def two_factor_enabled?
|
||||||
find_user.try(:otp_required_for_login?)
|
find_user.try(:otp_required_for_login?)
|
||||||
end
|
end
|
||||||
@@ -83,7 +61,7 @@ class Auth::SessionsController < Devise::SessionsController
|
|||||||
|
|
||||||
if user_params[:otp_attempt].present? && session[:otp_user_id]
|
if user_params[:otp_attempt].present? && session[:otp_user_id]
|
||||||
authenticate_with_two_factor_via_otp(user)
|
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)
|
prompt_for_two_factor(user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -106,14 +84,6 @@ class Auth::SessionsController < Devise::SessionsController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_pack
|
|
||||||
use_pack 'auth'
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_instance_presenter
|
|
||||||
@instance_presenter = InstancePresenter.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def home_paths(resource)
|
def home_paths(resource)
|
||||||
paths = [about_path]
|
paths = [about_path]
|
||||||
if single_user_mode? && resource.is_a?(User)
|
if single_user_mode? && resource.is_a?(User)
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ class AuthorizeFollowsController < ApplicationController
|
|||||||
layout 'modal'
|
layout 'modal'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_pack
|
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@account = located_account || render(:error)
|
@account = located_account || render(:error)
|
||||||
@@ -25,10 +23,6 @@ class AuthorizeFollowsController < ApplicationController
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_pack
|
|
||||||
use_pack 'modal'
|
|
||||||
end
|
|
||||||
|
|
||||||
def follow_attempt
|
def follow_attempt
|
||||||
FollowService.new.call(current_account, acct_without_prefix)
|
FollowService.new.call(current_account, acct_without_prefix)
|
||||||
end
|
end
|
||||||
@@ -46,7 +40,7 @@ class AuthorizeFollowsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def account_from_remote_follow
|
def account_from_remote_follow
|
||||||
ResolveAccountService.new.call(acct_without_prefix)
|
ResolveRemoteAccountService.new.call(acct_without_prefix)
|
||||||
end
|
end
|
||||||
|
|
||||||
def acct_param_is_url?
|
def acct_param_is_url?
|
||||||
@@ -64,8 +58,4 @@ class AuthorizeFollowsController < ApplicationController
|
|||||||
def acct_params
|
def acct_params
|
||||||
params.fetch(:acct, '')
|
params.fetch(:acct, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'modal-layout'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user