Compare commits
44 Commits
cybrespace
...
cybrespace
Author | SHA1 | Date |
---|---|---|
chr | 19780fe584 | |
Eugen Rochko | 612d02028c | |
Eugen Rochko | f100e84372 | |
ThibG | 31a209cb01 | |
Eugen Rochko | 13a062a5d9 | |
chr | 02fdc0d5c6 | |
blackle | b820776a98 | |
chr | b41247ecf0 | |
chr | dc0b442228 | |
chr | 7f583e3f0f | |
chr | c9ae6c6be8 | |
chr | 378f3e41b6 | |
chr | 5c6be91d86 | |
chr | f6a8ac76b6 | |
chr | 21d6a10707 | |
chr | d74271faa9 | |
chr | c231e16adb | |
nightpool | 46566ffcb6 | |
Andrew | fcc5feceab | |
Andrew | 014b564f12 | |
Andrew | c22efcaee7 | |
Andrew | e5bb9455a3 | |
Andrew | f5f007f5e0 | |
Ondřej Hruška | 1b9efd28c8 | |
Ondřej Hruška | 71f86dc99d | |
Ondřej Hruška | 835c4281ba | |
Ondřej Hruška | 825f9449d5 | |
nightpool | d81e1e5554 | |
Andrew | f8d0ebbe4f | |
nightpool | 98232134f8 | |
nightpool | e82de8035d | |
nightpool | 18238ba71d | |
nightpool | b31f0072e4 | |
nightpool | 998baec655 | |
Andrew | 423604bc03 | |
Andrew | d6dd4a21ea | |
Andrew | 3bb71deb4f | |
chr | d06b6340ff | |
chr | eba9da0297 | |
chr | f23bacf504 | |
Andrew | c06366cf09 | |
nightpool | 7b760d60c5 | |
Andrew | 8626ba1f6b | |
Andrew | 618a8c2a4d |
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"react",
|
||||||
|
[
|
||||||
|
"env",
|
||||||
|
{
|
||||||
|
"exclude": ["transform-async-to-generator", "transform-regenerator"],
|
||||||
|
"loose": true,
|
||||||
|
"modules": false,
|
||||||
|
"targets": {
|
||||||
|
"browsers": ["last 2 versions", "IE >= 11", "iOS >= 9"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"syntax-dynamic-import",
|
||||||
|
["transform-object-rest-spread", { "useBuiltIns": true }],
|
||||||
|
"transform-decorators-legacy",
|
||||||
|
"transform-class-properties",
|
||||||
|
[
|
||||||
|
"react-intl",
|
||||||
|
{
|
||||||
|
"messagesDir": "./build/messages"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preval"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"development": {
|
||||||
|
"plugins": [
|
||||||
|
"transform-react-jsx-source",
|
||||||
|
"transform-react-jsx-self"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"plugins": [
|
||||||
|
"lodash",
|
||||||
|
[
|
||||||
|
"transform-react-remove-prop-types",
|
||||||
|
{
|
||||||
|
"mode": "remove",
|
||||||
|
"removeImport": true,
|
||||||
|
"additionalLibraries": [
|
||||||
|
"react-immutable-proptypes"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"transform-react-inline-elements",
|
||||||
|
[
|
||||||
|
"transform-runtime",
|
||||||
|
{
|
||||||
|
"helpers": true,
|
||||||
|
"polyfill": false,
|
||||||
|
"regenerator": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"plugins": [
|
||||||
|
"transform-es2015-modules-commonjs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
https://github.com/heroku/heroku-buildpack-apt
|
https://github.com/heroku/heroku-buildpack-apt
|
||||||
https://github.com/Scalingo/ffmpeg-buildpack
|
|
||||||
https://github.com/Scalingo/nodejs-buildpack
|
https://github.com/Scalingo/nodejs-buildpack
|
||||||
https://github.com/Scalingo/ruby-buildpack
|
https://github.com/Scalingo/ruby-buildpack
|
||||||
|
|
|
@ -13,9 +13,6 @@ aliases:
|
||||||
ALLOW_NOPAM: true
|
ALLOW_NOPAM: true
|
||||||
CONTINUOUS_INTEGRATION: true
|
CONTINUOUS_INTEGRATION: true
|
||||||
DISABLE_SIMPLECOV: true
|
DISABLE_SIMPLECOV: true
|
||||||
PAM_ENABLED: true
|
|
||||||
PAM_DEFAULT_SERVICE: pam_test
|
|
||||||
PAM_CONTROLLED_SERVICE: pam_test_controlled
|
|
||||||
working_directory: ~/projects/mastodon/
|
working_directory: ~/projects/mastodon/
|
||||||
|
|
||||||
- &attach_workspace
|
- &attach_workspace
|
||||||
|
@ -67,17 +64,12 @@ aliases:
|
||||||
|
|
||||||
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
|
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
|
||||||
- *restore_ruby_dependencies
|
- *restore_ruby_dependencies
|
||||||
- run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production && bundle clean
|
- run: bundle install --clean --jobs 16 --path ./vendor/bundle/ --retry 3 --with pam_authentication --without development production
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
|
key: v2-ruby-dependencies-{{ checksum "/tmp/.ruby-version" }}-{{ checksum "Gemfile.lock" }}
|
||||||
paths:
|
paths:
|
||||||
- ./.bundle/
|
- ./.bundle/
|
||||||
- ./vendor/bundle/
|
- ./vendor/bundle/
|
||||||
- persist_to_workspace:
|
|
||||||
root: ~/projects/
|
|
||||||
paths:
|
|
||||||
- ./mastodon/.bundle/
|
|
||||||
- ./mastodon/vendor/bundle/
|
|
||||||
|
|
||||||
- &test_steps
|
- &test_steps
|
||||||
steps:
|
steps:
|
||||||
|
@ -86,6 +78,15 @@ aliases:
|
||||||
- *install_system_dependencies
|
- *install_system_dependencies
|
||||||
- run: sudo apt-get install -y ffmpeg
|
- run: sudo apt-get install -y ffmpeg
|
||||||
|
|
||||||
|
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
|
||||||
|
- *restore_ruby_dependencies
|
||||||
|
|
||||||
|
- restore_cache:
|
||||||
|
keys:
|
||||||
|
- precompiled-assets-{{ .Branch }}-{{ .Revision }}
|
||||||
|
- precompiled-assets-{{ .Branch }}-
|
||||||
|
- precompiled-assets-
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Prepare Tests
|
name: Prepare Tests
|
||||||
command: ./bin/rails parallel:create parallel:load_schema parallel:prepare
|
command: ./bin/rails parallel:create parallel:load_schema parallel:prepare
|
||||||
|
@ -121,12 +122,14 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- *attach_workspace
|
- *attach_workspace
|
||||||
- *install_system_dependencies
|
- *install_system_dependencies
|
||||||
|
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
|
||||||
|
- *restore_ruby_dependencies
|
||||||
- run: ./bin/rails assets:precompile
|
- run: ./bin/rails assets:precompile
|
||||||
- persist_to_workspace:
|
- save_cache:
|
||||||
root: ~/projects/
|
key: precompiled-assets-{{ .Branch }}-{{ .Revision }}
|
||||||
paths:
|
paths:
|
||||||
- ./mastodon/public/assets
|
- ./public/assets
|
||||||
- ./mastodon/public/packs-test/
|
- ./public/packs-test/
|
||||||
|
|
||||||
test-ruby2.5:
|
test-ruby2.5:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
|
@ -173,10 +176,10 @@ jobs:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
steps:
|
steps:
|
||||||
- *attach_workspace
|
- *attach_workspace
|
||||||
|
- run: ruby -e 'puts RUBY_VERSION' | tee /tmp/.ruby-version
|
||||||
|
- *restore_ruby_dependencies
|
||||||
- run: bundle exec i18n-tasks check-normalized
|
- run: bundle exec i18n-tasks check-normalized
|
||||||
- run: bundle exec i18n-tasks unused
|
- run: bundle exec i18n-tasks unused
|
||||||
- run: bundle exec i18n-tasks missing -t plural
|
|
||||||
- run: bundle exec i18n-tasks check-consistent-interpolations
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
|
@ -189,11 +192,9 @@ workflows:
|
||||||
- install-ruby2.4:
|
- install-ruby2.4:
|
||||||
requires:
|
requires:
|
||||||
- install
|
- install
|
||||||
- install-ruby2.5
|
|
||||||
- install-ruby2.3:
|
- install-ruby2.3:
|
||||||
requires:
|
requires:
|
||||||
- install
|
- install
|
||||||
- install-ruby2.5
|
|
||||||
- build:
|
- build:
|
||||||
requires:
|
requires:
|
||||||
- install-ruby2.5
|
- install-ruby2.5
|
||||||
|
|
|
@ -136,8 +136,8 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io
|
||||||
# Defaults to 60 seconds. Set to 0 to disable
|
# Defaults to 60 seconds. Set to 0 to disable
|
||||||
# SWIFT_CACHE_TTL=
|
# SWIFT_CACHE_TTL=
|
||||||
|
|
||||||
# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
|
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||||
# S3_ALIAS_HOST=
|
# S3_CLOUDFRONT_HOST=
|
||||||
|
|
||||||
# Streaming API integration
|
# Streaming API integration
|
||||||
# STREAMING_API_BASE_URL=
|
# STREAMING_API_BASE_URL=
|
||||||
|
|
|
@ -134,8 +134,8 @@ SMTP_FROM_ADDRESS=notifications@example.com
|
||||||
# Defaults to 60 seconds. Set to 0 to disable
|
# Defaults to 60 seconds. Set to 0 to disable
|
||||||
# SWIFT_CACHE_TTL=
|
# SWIFT_CACHE_TTL=
|
||||||
|
|
||||||
# Optional alias for S3 (e.g. to serve files on a custom domain, possibly using Cloudfront or Cloudflare)
|
# Optional alias for S3 if you want to use Cloudfront or Cloudflare in front
|
||||||
# S3_ALIAS_HOST=
|
# S3_CLOUDFRONT_HOST=
|
||||||
|
|
||||||
# Streaming API integration
|
# Streaming API integration
|
||||||
# STREAMING_API_BASE_URL=
|
# STREAMING_API_BASE_URL=
|
||||||
|
@ -162,7 +162,6 @@ STREAMING_CLUSTER_NUM=1
|
||||||
# LDAP_BIND_DN=
|
# LDAP_BIND_DN=
|
||||||
# LDAP_PASSWORD=
|
# LDAP_PASSWORD=
|
||||||
# LDAP_UID=cn
|
# LDAP_UID=cn
|
||||||
# LDAP_SEARCH_FILTER="%{uid}=%{email}"
|
|
||||||
|
|
||||||
# PAM authentication (optional)
|
# PAM authentication (optional)
|
||||||
# PAM authentication uses for the email generation the "email" pam variable
|
# PAM authentication uses for the email generation the "email" pam variable
|
||||||
|
|
|
@ -3,3 +3,7 @@ NODE_ENV=test
|
||||||
# Federation
|
# Federation
|
||||||
LOCAL_DOMAIN=cb6e6126.ngrok.io
|
LOCAL_DOMAIN=cb6e6126.ngrok.io
|
||||||
LOCAL_HTTPS=true
|
LOCAL_HTTPS=true
|
||||||
|
# test pam authentication
|
||||||
|
PAM_ENABLED=true
|
||||||
|
PAM_DEFAULT_SERVICE=pam_test
|
||||||
|
PAM_CONTROLLED_SERVICE=pam_test_controlled
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
VAGRANT=true
|
VAGRANT=true
|
||||||
LOCAL_DOMAIN=mastodon.local
|
LOCAL_DOMAIN=mastodon.dev
|
|
@ -1,27 +1,12 @@
|
||||||
---
|
---
|
||||||
name: Bug Report
|
name: Bug Report
|
||||||
about: If something isn't working as expected
|
about: Create a report to help us improve
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- Make sure that you are submitting a new bug that was not previously reported or already fixed -->
|
[Issue text goes here].
|
||||||
|
|
||||||
<!-- Please use a concise and distinct title for the issue -->
|
* * * *
|
||||||
|
|
||||||
### Expected behaviour
|
- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate.
|
||||||
|
- [ ] This bug happens on a [tagged release](https://github.com/tootsuite/mastodon/releases) and not on `master` (If you're a user, don't worry about this).
|
||||||
<!-- What should have happened? -->
|
|
||||||
|
|
||||||
### Actual behaviour
|
|
||||||
|
|
||||||
<!-- What happened? -->
|
|
||||||
|
|
||||||
### Steps to reproduce the problem
|
|
||||||
|
|
||||||
<!-- What were you trying to do? -->
|
|
||||||
|
|
||||||
### Specifications
|
|
||||||
|
|
||||||
<!-- What version or commit hash of Mastodon did you find this bug in? -->
|
|
||||||
|
|
||||||
<!-- If a front-end issue, what browser and operating systems were you using? -->
|
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
---
|
---
|
||||||
name: Feature Request
|
name: Feature Request
|
||||||
about: I have a suggestion
|
about: Suggest an idea for this project
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- Please use a concise and distinct title for the issue -->
|
[Issue text goes here].
|
||||||
|
|
||||||
<!-- Consider: Could it be implemented as a 3rd party app using the REST API instead? -->
|
* * * *
|
||||||
|
|
||||||
### Pitch
|
- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate.
|
||||||
|
|
||||||
<!-- Describe your idea for a feature. Make sure it has not already been suggested/implemented/turned down before -->
|
|
||||||
|
|
||||||
### Motivation
|
|
||||||
|
|
||||||
<!-- Why do you think this feature is needed? Who would benefit from it? -->
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
---
|
|
||||||
name: Support
|
|
||||||
about: Ask for help with your deployment
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
We primarily use GitHub as a bug and feature tracker. For usage questions, troubleshooting of deployments and other individual technical assistance, please use one of the resources below:
|
|
||||||
|
|
||||||
- https://discourse.joinmastodon.org
|
|
||||||
- #mastodon on irc.freenode.net
|
|
12
.rubocop.yml
|
@ -11,7 +11,6 @@ AllCops:
|
||||||
- 'Vagrantfile'
|
- 'Vagrantfile'
|
||||||
- 'vendor/**/*'
|
- 'vendor/**/*'
|
||||||
- 'lib/json_ld/*'
|
- 'lib/json_ld/*'
|
||||||
- 'lib/templates/**/*'
|
|
||||||
|
|
||||||
Bundler/OrderedGems:
|
Bundler/OrderedGems:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
@ -62,9 +61,6 @@ Metrics/ParameterLists:
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Max: 20
|
Max: 20
|
||||||
|
|
||||||
Naming/MemoizedInstanceVariableName:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Rails:
|
Rails:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
@ -74,14 +70,6 @@ Rails/HasAndBelongsToMany:
|
||||||
Rails/SkipsModelValidations:
|
Rails/SkipsModelValidations:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
Rails/HttpStatus:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
Rails/Exit:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/mastodon/*'
|
|
||||||
- 'lib/cli'
|
|
||||||
|
|
||||||
Style/ClassAndModuleChildren:
|
Style/ClassAndModuleChildren:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.5.3
|
2.5.1
|
||||||
|
|
368
AUTHORS.md
|
@ -3,85 +3,76 @@ and provided thanks to the work of the following contributors:
|
||||||
|
|
||||||
* [Gargron](https://github.com/Gargron)
|
* [Gargron](https://github.com/Gargron)
|
||||||
* [ykzts](https://github.com/ykzts)
|
* [ykzts](https://github.com/ykzts)
|
||||||
* [akihikodaki](https://github.com/akihikodaki)
|
|
||||||
* [mjankowski](https://github.com/mjankowski)
|
* [mjankowski](https://github.com/mjankowski)
|
||||||
* [ThibG](https://github.com/ThibG)
|
* [akihikodaki](https://github.com/akihikodaki)
|
||||||
* [unarist](https://github.com/unarist)
|
* [unarist](https://github.com/unarist)
|
||||||
* [m4sk1n](https://github.com/m4sk1n)
|
|
||||||
* [yiskah](https://github.com/yiskah)
|
* [yiskah](https://github.com/yiskah)
|
||||||
|
* [m4sk1n](https://github.com/m4sk1n)
|
||||||
* [nolanlawson](https://github.com/nolanlawson)
|
* [nolanlawson](https://github.com/nolanlawson)
|
||||||
* [sorin-davidoi](https://github.com/sorin-davidoi)
|
* [sorin-davidoi](https://github.com/sorin-davidoi)
|
||||||
* [abcang](https://github.com/abcang)
|
* [abcang](https://github.com/abcang)
|
||||||
|
* [ThibG](https://github.com/ThibG)
|
||||||
* [lynlynlynx](https://github.com/lynlynlynx)
|
* [lynlynlynx](https://github.com/lynlynlynx)
|
||||||
* [dependabot[bot]](https://github.com/apps/dependabot)
|
|
||||||
* [alpaca-tc](https://github.com/alpaca-tc)
|
* [alpaca-tc](https://github.com/alpaca-tc)
|
||||||
* [nclm](https://github.com/nclm)
|
* [nclm](https://github.com/nclm)
|
||||||
* [ineffyble](https://github.com/ineffyble)
|
* [ineffyble](https://github.com/ineffyble)
|
||||||
* [renatolond](https://github.com/renatolond)
|
|
||||||
* [jeroenpraat](https://github.com/jeroenpraat)
|
* [jeroenpraat](https://github.com/jeroenpraat)
|
||||||
* [mayaeh](https://github.com/mayaeh)
|
|
||||||
* [blackle](https://github.com/blackle)
|
* [blackle](https://github.com/blackle)
|
||||||
* [Quent-in](https://github.com/Quent-in)
|
* [Quent-in](https://github.com/Quent-in)
|
||||||
* [JantsoP](https://github.com/JantsoP)
|
* [JantsoP](https://github.com/JantsoP)
|
||||||
* [nullkal](https://github.com/nullkal)
|
* [nullkal](https://github.com/nullkal)
|
||||||
* [yookoala](https://github.com/yookoala)
|
* [yookoala](https://github.com/yookoala)
|
||||||
* [mabkenar](https://github.com/mabkenar)
|
|
||||||
* [ysksn](https://github.com/ysksn)
|
* [ysksn](https://github.com/ysksn)
|
||||||
* [shuheiktgw](https://github.com/shuheiktgw)
|
|
||||||
* [ashfurrow](https://github.com/ashfurrow)
|
* [ashfurrow](https://github.com/ashfurrow)
|
||||||
* [Kjwon15](https://github.com/Kjwon15)
|
|
||||||
* [zunda](https://github.com/zunda)
|
|
||||||
* [eramdam](https://github.com/eramdam)
|
* [eramdam](https://github.com/eramdam)
|
||||||
* [masarakki](https://github.com/masarakki)
|
* [mayaeh](https://github.com/mayaeh)
|
||||||
* [takayamaki](https://github.com/takayamaki)
|
* [zunda](https://github.com/zunda)
|
||||||
* [ticky](https://github.com/ticky)
|
* [ticky](https://github.com/ticky)
|
||||||
* [Quenty31](https://github.com/Quenty31)
|
* [masarakki](https://github.com/masarakki)
|
||||||
* [danhunsaker](https://github.com/danhunsaker)
|
|
||||||
* [ThisIsMissEm](https://github.com/ThisIsMissEm)
|
|
||||||
* [hcmiya](https://github.com/hcmiya)
|
|
||||||
* [stephenburgess8](https://github.com/stephenburgess8)
|
|
||||||
* [Wonderfall](https://github.com/Wonderfall)
|
* [Wonderfall](https://github.com/Wonderfall)
|
||||||
* [matteoaquila](https://github.com/matteoaquila)
|
* [matteoaquila](https://github.com/matteoaquila)
|
||||||
* [rkarabut](https://github.com/rkarabut)
|
* [rkarabut](https://github.com/rkarabut)
|
||||||
* [yukimochi](https://github.com/yukimochi)
|
* [stephenburgess8](https://github.com/stephenburgess8)
|
||||||
|
* [Kjwon15](https://github.com/Kjwon15)
|
||||||
* [Artoria2e5](https://github.com/Artoria2e5)
|
* [Artoria2e5](https://github.com/Artoria2e5)
|
||||||
|
* [yukimochi](https://github.com/yukimochi)
|
||||||
* [marrus-sh](https://github.com/marrus-sh)
|
* [marrus-sh](https://github.com/marrus-sh)
|
||||||
* [krainboltgreene](https://github.com/krainboltgreene)
|
* [krainboltgreene](https://github.com/krainboltgreene)
|
||||||
* [patf](https://github.com/patf)
|
* [renatolond](https://github.com/renatolond)
|
||||||
* [Aldarone](https://github.com/Aldarone)
|
|
||||||
* [BoFFire](https://github.com/BoFFire)
|
* [BoFFire](https://github.com/BoFFire)
|
||||||
* [clworld](https://github.com/clworld)
|
* [clworld](https://github.com/clworld)
|
||||||
* [dracos](https://github.com/dracos)
|
* [danhunsaker](https://github.com/danhunsaker)
|
||||||
* [SerCom_KC](mailto:sercom-kc@users.noreply.github.com)
|
* [patf](https://github.com/patf)
|
||||||
* [Sylvhem](https://github.com/Sylvhem)
|
* [Quenty31](https://github.com/Quenty31)
|
||||||
* [nightpool](https://github.com/nightpool)
|
* [MitarashiDango](https://github.com/MitarashiDango)
|
||||||
* [MasterGroosha](https://github.com/MasterGroosha)
|
* [Aldarone](https://github.com/Aldarone)
|
||||||
* [JeanGauthier](https://github.com/JeanGauthier)
|
* [JeanGauthier](https://github.com/JeanGauthier)
|
||||||
* [kschaper](https://github.com/kschaper)
|
* [kschaper](https://github.com/kschaper)
|
||||||
* [MaciekBaron](https://github.com/MaciekBaron)
|
* [takayamaki](https://github.com/takayamaki)
|
||||||
* [MitarashiDango](mailto:mitarashidango@users.noreply.github.com)
|
|
||||||
* [beatrix-bitrot](https://github.com/beatrix-bitrot)
|
|
||||||
* [adbelle](https://github.com/adbelle)
|
* [adbelle](https://github.com/adbelle)
|
||||||
* [evanminto](https://github.com/evanminto)
|
* [evanminto](https://github.com/evanminto)
|
||||||
|
* [mabkenar](https://github.com/mabkenar)
|
||||||
* [MightyPork](https://github.com/MightyPork)
|
* [MightyPork](https://github.com/MightyPork)
|
||||||
|
* [beatrix-bitrot](https://github.com/beatrix-bitrot)
|
||||||
* [yhirano55](https://github.com/yhirano55)
|
* [yhirano55](https://github.com/yhirano55)
|
||||||
* [camponez](https://github.com/camponez)
|
* [camponez](https://github.com/camponez)
|
||||||
* [SerCom-KC](https://github.com/SerCom-KC)
|
|
||||||
* [aschmitz](https://github.com/aschmitz)
|
* [aschmitz](https://github.com/aschmitz)
|
||||||
* [devkral](https://github.com/devkral)
|
|
||||||
* [fpiesche](https://github.com/fpiesche)
|
* [fpiesche](https://github.com/fpiesche)
|
||||||
* [gandaro](https://github.com/gandaro)
|
* [gandaro](https://github.com/gandaro)
|
||||||
* [johnsudaar](https://github.com/johnsudaar)
|
* [johnsudaar](https://github.com/johnsudaar)
|
||||||
* [trebmuh](https://github.com/trebmuh)
|
* [trebmuh](https://github.com/trebmuh)
|
||||||
* [Rakib Hasan](mailto:rmhasan@gmail.com)
|
* [Sylvhem](https://github.com/Sylvhem)
|
||||||
* [lindwurm](https://github.com/lindwurm)
|
* [lindwurm](https://github.com/lindwurm)
|
||||||
* [victorhck](mailto:victorhck@geeko.site)
|
|
||||||
* [voidsatisfaction](https://github.com/voidsatisfaction)
|
* [voidsatisfaction](https://github.com/voidsatisfaction)
|
||||||
|
* [neetshin](https://github.com/neetshin)
|
||||||
|
* [valentin2105](https://github.com/valentin2105)
|
||||||
* [hikari-no-yume](https://github.com/hikari-no-yume)
|
* [hikari-no-yume](https://github.com/hikari-no-yume)
|
||||||
* [angristan](https://github.com/angristan)
|
* [Angristan](https://github.com/Angristan)
|
||||||
* [seefood](https://github.com/seefood)
|
* [seefood](https://github.com/seefood)
|
||||||
* [jackjennings](https://github.com/jackjennings)
|
* [jackjennings](https://github.com/jackjennings)
|
||||||
* [spla](mailto:spla@mastodont.cat)
|
* [hcmiya](https://github.com/hcmiya)
|
||||||
|
* [nightpool](https://github.com/nightpool)
|
||||||
|
* [salvadorpla](https://github.com/salvadorpla)
|
||||||
* [expenses](https://github.com/expenses)
|
* [expenses](https://github.com/expenses)
|
||||||
* [walf443](https://github.com/walf443)
|
* [walf443](https://github.com/walf443)
|
||||||
* [JoelQ](https://github.com/JoelQ)
|
* [JoelQ](https://github.com/JoelQ)
|
||||||
|
@ -93,93 +84,74 @@ and provided thanks to the work of the following contributors:
|
||||||
* [tsuwatch](https://github.com/tsuwatch)
|
* [tsuwatch](https://github.com/tsuwatch)
|
||||||
* [victorhck](https://github.com/victorhck)
|
* [victorhck](https://github.com/victorhck)
|
||||||
* [puckipedia](https://github.com/puckipedia)
|
* [puckipedia](https://github.com/puckipedia)
|
||||||
* [fvh-P](https://github.com/fvh-P)
|
|
||||||
* [contraexemplo](https://github.com/contraexemplo)
|
* [contraexemplo](https://github.com/contraexemplo)
|
||||||
* [hugogameiro](https://github.com/hugogameiro)
|
|
||||||
* [kazu9su](https://github.com/kazu9su)
|
* [kazu9su](https://github.com/kazu9su)
|
||||||
* [Komic](https://github.com/Komic)
|
* [Komic](https://github.com/Komic)
|
||||||
* [diomed](https://github.com/diomed)
|
* [diomed](https://github.com/diomed)
|
||||||
* [ariasuni](https://github.com/ariasuni)
|
|
||||||
* [Neetshin](mailto:neetshin@neetsh.in)
|
|
||||||
* [rainyday](https://github.com/rainyday)
|
* [rainyday](https://github.com/rainyday)
|
||||||
* [ProgVal](https://github.com/ProgVal)
|
|
||||||
* [valentin2105](https://github.com/valentin2105)
|
|
||||||
* [yuntan](https://github.com/yuntan)
|
|
||||||
* [ashleyhull-versent](https://github.com/ashleyhull-versent)
|
|
||||||
* [goofy-bz](mailto:goofy@babelzilla.org)
|
|
||||||
* [kadiix](https://github.com/kadiix)
|
* [kadiix](https://github.com/kadiix)
|
||||||
* [kodacs](https://github.com/kodacs)
|
* [kodacs](https://github.com/kodacs)
|
||||||
* [rtucker](https://github.com/rtucker)
|
* [ProgVal](https://github.com/ProgVal)
|
||||||
* [KScl](https://github.com/KScl)
|
|
||||||
* [sterdev](https://github.com/sterdev)
|
* [sterdev](https://github.com/sterdev)
|
||||||
* [TheKinrar](https://github.com/TheKinrar)
|
* [TheKinrar](https://github.com/TheKinrar)
|
||||||
* [AA4ch1](https://github.com/AA4ch1)
|
* [AA4ch1](https://github.com/AA4ch1)
|
||||||
* [alexgleason](https://github.com/alexgleason)
|
* [alexgleason](https://github.com/alexgleason)
|
||||||
* [cpytel](https://github.com/cpytel)
|
* [cpytel](https://github.com/cpytel)
|
||||||
* [northerner](https://github.com/northerner)
|
* [northerner](https://github.com/northerner)
|
||||||
* [fhemberger](https://github.com/fhemberger)
|
|
||||||
* [greysteil](https://github.com/greysteil)
|
|
||||||
* [hnrysmth](https://github.com/hnrysmth)
|
* [hnrysmth](https://github.com/hnrysmth)
|
||||||
* [d6rkaiz](https://github.com/d6rkaiz)
|
* [hugogameiro](https://github.com/hugogameiro)
|
||||||
* [JMendyk](https://github.com/JMendyk)
|
|
||||||
* [JohnD28](https://github.com/JohnD28)
|
* [JohnD28](https://github.com/JohnD28)
|
||||||
* [znz](https://github.com/znz)
|
* [znz](https://github.com/znz)
|
||||||
* [Naouak](https://github.com/Naouak)
|
* [Naouak](https://github.com/Naouak)
|
||||||
|
* [rtucker](https://github.com/rtucker)
|
||||||
* [reneklacan](https://github.com/reneklacan)
|
* [reneklacan](https://github.com/reneklacan)
|
||||||
* [ekiru](https://github.com/ekiru)
|
* [KScl](https://github.com/KScl)
|
||||||
|
* [SerCom-KC](https://github.com/SerCom-KC)
|
||||||
* [tcitworld](https://github.com/tcitworld)
|
* [tcitworld](https://github.com/tcitworld)
|
||||||
* [geta6](https://github.com/geta6)
|
* [geta6](https://github.com/geta6)
|
||||||
|
* [goofy-bz](https://github.com/goofy-bz)
|
||||||
* [happycoloredbanana](https://github.com/happycoloredbanana)
|
* [happycoloredbanana](https://github.com/happycoloredbanana)
|
||||||
* [kedamaDQ](https://github.com/kedamaDQ)
|
|
||||||
* [leopku](https://github.com/leopku)
|
* [leopku](https://github.com/leopku)
|
||||||
* [SansPseudoFix](https://github.com/SansPseudoFix)
|
* [SansPseudoFix](https://github.com/SansPseudoFix)
|
||||||
* [tomfhowe](https://github.com/tomfhowe)
|
* [tomfhowe](https://github.com/tomfhowe)
|
||||||
* [noraworld](https://github.com/noraworld)
|
* [noraworld](https://github.com/noraworld)
|
||||||
* [theboss](https://github.com/theboss)
|
* [fvh-P](https://github.com/fvh-P)
|
||||||
* [178inaba](https://github.com/178inaba)
|
* [178inaba](https://github.com/178inaba)
|
||||||
|
* [devkral](https://github.com/devkral)
|
||||||
* [alyssais](https://github.com/alyssais)
|
* [alyssais](https://github.com/alyssais)
|
||||||
* [kodnaplakal](https://github.com/kodnaplakal)
|
* [kodnaplakal](https://github.com/kodnaplakal)
|
||||||
* [stalker314314](https://github.com/stalker314314)
|
* [stalker314314](https://github.com/stalker314314)
|
||||||
* [huertanix](https://github.com/huertanix)
|
* [huertanix](https://github.com/huertanix)
|
||||||
* [genesixx](https://github.com/genesixx)
|
* [genesixx](https://github.com/genesixx)
|
||||||
|
* [fhemberger](https://github.com/fhemberger)
|
||||||
* [halkeye](https://github.com/halkeye)
|
* [halkeye](https://github.com/halkeye)
|
||||||
* [hinaloe](https://github.com/hinaloe)
|
|
||||||
* [treby](https://github.com/treby)
|
* [treby](https://github.com/treby)
|
||||||
* [Reverite](https://github.com/Reverite)
|
* [d6rkaiz](https://github.com/d6rkaiz)
|
||||||
* [jpdevries](https://github.com/jpdevries)
|
* [jpdevries](https://github.com/jpdevries)
|
||||||
* [H-C-F](https://github.com/H-C-F)
|
* [rndm-stranger](https://github.com/rndm-stranger)
|
||||||
* [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name)
|
|
||||||
* [saper](https://github.com/saper)
|
* [saper](https://github.com/saper)
|
||||||
* [nevillepark](https://github.com/nevillepark)
|
* [nevillepark](https://github.com/nevillepark)
|
||||||
* [ornithocoder](https://github.com/ornithocoder)
|
* [ornithocoder](https://github.com/ornithocoder)
|
||||||
* [pierreozoux](https://github.com/pierreozoux)
|
* [pierreozoux](https://github.com/pierreozoux)
|
||||||
* [qguv](https://github.com/qguv)
|
* [ramlmn](https://github.com/ramlmn)
|
||||||
* [Ram Lmn](mailto:ramlmn@users.noreply.github.com)
|
|
||||||
* [harukasan](https://github.com/harukasan)
|
* [harukasan](https://github.com/harukasan)
|
||||||
* [stamak](https://github.com/stamak)
|
* [stamak](https://github.com/stamak)
|
||||||
* [Technowix](mailto:technowix@users.noreply.github.com)
|
|
||||||
* [Eychics](https://github.com/Eychics)
|
* [Eychics](https://github.com/Eychics)
|
||||||
* [Thor Harald Johansen](mailto:thj@thj.no)
|
* [thor-the-norseman](https://github.com/thor-the-norseman)
|
||||||
* [0x70b1a5](https://github.com/0x70b1a5)
|
* [0x70b1a5](https://github.com/0x70b1a5)
|
||||||
* [gled-rs](https://github.com/gled-rs)
|
* [gled-rs](https://github.com/gled-rs)
|
||||||
* [Valentin_NC](mailto:valentin.ouvrard@nautile.sarl)
|
|
||||||
* [R0ckweb](https://github.com/R0ckweb)
|
* [R0ckweb](https://github.com/R0ckweb)
|
||||||
* [caasi](https://github.com/caasi)
|
|
||||||
* [esetomo](https://github.com/esetomo)
|
* [esetomo](https://github.com/esetomo)
|
||||||
* [foxiehkins](https://github.com/foxiehkins)
|
* [foxiehkins](https://github.com/foxiehkins)
|
||||||
* [hoodie](mailto:hoodiekitten@outlook.com)
|
* [sdukhovni](https://github.com/sdukhovni)
|
||||||
* [luzi82](https://github.com/luzi82)
|
|
||||||
* [duxovni](https://github.com/duxovni)
|
|
||||||
* [unsmell](https://github.com/unsmell)
|
* [unsmell](https://github.com/unsmell)
|
||||||
* [chriswmartin](https://github.com/chriswmartin)
|
* [chriswmartin](https://github.com/chriswmartin)
|
||||||
* [vahnj](https://github.com/vahnj)
|
* [vahnj](https://github.com/vahnj)
|
||||||
* [ikuradon](https://github.com/ikuradon)
|
* [ikuradon](https://github.com/ikuradon)
|
||||||
* [AndreLewin](https://github.com/AndreLewin)
|
* [AndreLewin](https://github.com/AndreLewin)
|
||||||
* [rinsuki](https://github.com/rinsuki)
|
|
||||||
* [redtachyons](https://github.com/redtachyons)
|
* [redtachyons](https://github.com/redtachyons)
|
||||||
* [thurloat](https://github.com/thurloat)
|
* [thurloat](https://github.com/thurloat)
|
||||||
* [aaribaud](https://github.com/aaribaud)
|
* [aaribaud](https://github.com/aaribaud)
|
||||||
* [Andrew](mailto:andrewlchronister@gmail.com)
|
|
||||||
* [estuans](https://github.com/estuans)
|
* [estuans](https://github.com/estuans)
|
||||||
* [dissolve](https://github.com/dissolve)
|
* [dissolve](https://github.com/dissolve)
|
||||||
* [PurpleBooth](https://github.com/PurpleBooth)
|
* [PurpleBooth](https://github.com/PurpleBooth)
|
||||||
|
@ -193,46 +165,36 @@ and provided thanks to the work of the following contributors:
|
||||||
* [farlistener](https://github.com/farlistener)
|
* [farlistener](https://github.com/farlistener)
|
||||||
* [DavidLibeau](https://github.com/DavidLibeau)
|
* [DavidLibeau](https://github.com/DavidLibeau)
|
||||||
* [SirCmpwn](https://github.com/SirCmpwn)
|
* [SirCmpwn](https://github.com/SirCmpwn)
|
||||||
|
* [MasterGroosha](https://github.com/MasterGroosha)
|
||||||
* [Fjoerfoks](https://github.com/Fjoerfoks)
|
* [Fjoerfoks](https://github.com/Fjoerfoks)
|
||||||
* [fmauNeko](https://github.com/fmauNeko)
|
* [fmauNeko](https://github.com/fmauNeko)
|
||||||
* [gloaec](https://github.com/gloaec)
|
* [gloaec](https://github.com/gloaec)
|
||||||
* [Gomasy](https://github.com/Gomasy)
|
* [greysteil](https://github.com/greysteil)
|
||||||
* [unstabler](https://github.com/unstabler)
|
* [unstabler](https://github.com/unstabler)
|
||||||
* [potato4d](https://github.com/potato4d)
|
* [potato4d](https://github.com/potato4d)
|
||||||
* [h-izumi](https://github.com/h-izumi)
|
* [h-izumi](https://github.com/h-izumi)
|
||||||
* [ErikXXon](https://github.com/ErikXXon)
|
* [ErikXXon](https://github.com/ErikXXon)
|
||||||
* [ian-kelling](https://github.com/ian-kelling)
|
* [ian-kelling](https://github.com/ian-kelling)
|
||||||
* [immae](https://github.com/immae)
|
|
||||||
* [foozmeat](https://github.com/foozmeat)
|
* [foozmeat](https://github.com/foozmeat)
|
||||||
* [jasonrhodes](https://github.com/jasonrhodes)
|
* [jasonrhodes](https://github.com/jasonrhodes)
|
||||||
* [Jason Snell](mailto:jason@newrelic.com)
|
* [asm](https://github.com/asm)
|
||||||
* [jviide](https://github.com/jviide)
|
* [jviide](https://github.com/jviide)
|
||||||
* [crakaC](https://github.com/crakaC)
|
* [crakaC](https://github.com/crakaC)
|
||||||
* [tkbky](https://github.com/tkbky)
|
* [tkbky](https://github.com/tkbky)
|
||||||
* [Kaylee](mailto:kaylee@codethat.sucks)
|
|
||||||
* [Kazhnuz](https://github.com/Kazhnuz)
|
* [Kazhnuz](https://github.com/Kazhnuz)
|
||||||
* [connyduck](https://github.com/connyduck)
|
|
||||||
* [Lindsey Bieda](mailto:lindseyb@users.noreply.github.com)
|
|
||||||
* [Lorenz Diener](mailto:halcyon@icosahedron.website)
|
|
||||||
* [alimony](https://github.com/alimony)
|
* [alimony](https://github.com/alimony)
|
||||||
* [mig5](https://github.com/mig5)
|
* [mig5](https://github.com/mig5)
|
||||||
* [ndarville](https://github.com/ndarville)
|
* [ndarville](https://github.com/ndarville)
|
||||||
* [Abzol](https://github.com/Abzol)
|
* [Abzol](https://github.com/Abzol)
|
||||||
* [pwoolcoc](https://github.com/pwoolcoc)
|
|
||||||
* [xPaw](https://github.com/xPaw)
|
* [xPaw](https://github.com/xPaw)
|
||||||
* [petzah](https://github.com/petzah)
|
|
||||||
* [ignisf](https://github.com/ignisf)
|
|
||||||
* [raymestalez](https://github.com/raymestalez)
|
* [raymestalez](https://github.com/raymestalez)
|
||||||
* [sascha-sl](https://github.com/sascha-sl)
|
|
||||||
* [u1-liquid](https://github.com/u1-liquid)
|
|
||||||
* [sim6](https://github.com/sim6)
|
* [sim6](https://github.com/sim6)
|
||||||
* [stemid](https://github.com/stemid)
|
* [ekiru](https://github.com/ekiru)
|
||||||
|
* [Technowix](https://github.com/Technowix)
|
||||||
* [ThomasLeister](https://github.com/ThomasLeister)
|
* [ThomasLeister](https://github.com/ThomasLeister)
|
||||||
* [mcat-ee](https://github.com/mcat-ee)
|
* [mcat-ee](https://github.com/mcat-ee)
|
||||||
* [tototoshi](https://github.com/tototoshi)
|
* [tototoshi](https://github.com/tototoshi)
|
||||||
* [TrashMacNugget](https://github.com/TrashMacNugget)
|
|
||||||
* [VirtuBox](https://github.com/VirtuBox)
|
* [VirtuBox](https://github.com/VirtuBox)
|
||||||
* [Vladyslav](mailto:vaden@tuta.io)
|
|
||||||
* [kaniini](https://github.com/kaniini)
|
* [kaniini](https://github.com/kaniini)
|
||||||
* [vayan](https://github.com/vayan)
|
* [vayan](https://github.com/vayan)
|
||||||
* [yannicka](https://github.com/yannicka)
|
* [yannicka](https://github.com/yannicka)
|
||||||
|
@ -240,12 +202,7 @@ and provided thanks to the work of the following contributors:
|
||||||
* [zacanger](https://github.com/zacanger)
|
* [zacanger](https://github.com/zacanger)
|
||||||
* [amazedkoumei](https://github.com/amazedkoumei)
|
* [amazedkoumei](https://github.com/amazedkoumei)
|
||||||
* [anon5r](https://github.com/anon5r)
|
* [anon5r](https://github.com/anon5r)
|
||||||
* [aus-social](https://github.com/aus-social)
|
|
||||||
* [imbsky](https://github.com/imbsky)
|
|
||||||
* [bsky](mailto:me@imbsky.net)
|
|
||||||
* [chr-1x](https://github.com/chr-1x)
|
|
||||||
* [codl](https://github.com/codl)
|
* [codl](https://github.com/codl)
|
||||||
* [cpsdqs](https://github.com/cpsdqs)
|
|
||||||
* [barzamin](https://github.com/barzamin)
|
* [barzamin](https://github.com/barzamin)
|
||||||
* [fhalna](https://github.com/fhalna)
|
* [fhalna](https://github.com/fhalna)
|
||||||
* [haoyayoi](https://github.com/haoyayoi)
|
* [haoyayoi](https://github.com/haoyayoi)
|
||||||
|
@ -258,55 +215,42 @@ and provided thanks to the work of the following contributors:
|
||||||
* [oliverkeeble](https://github.com/oliverkeeble)
|
* [oliverkeeble](https://github.com/oliverkeeble)
|
||||||
* [pinfort](https://github.com/pinfort)
|
* [pinfort](https://github.com/pinfort)
|
||||||
* [rbaumert](https://github.com/rbaumert)
|
* [rbaumert](https://github.com/rbaumert)
|
||||||
* [rhoio](https://github.com/rhoio)
|
|
||||||
* [trwnh](https://github.com/trwnh)
|
|
||||||
* [usagi-f](https://github.com/usagi-f)
|
* [usagi-f](https://github.com/usagi-f)
|
||||||
* [vidarlee](https://github.com/vidarlee)
|
* [vidarlee](https://github.com/vidarlee)
|
||||||
* [vjackson725](https://github.com/vjackson725)
|
* [vjackson725](https://github.com/vjackson725)
|
||||||
* [wxcafe](https://github.com/wxcafe)
|
* [wxcafe](https://github.com/wxcafe)
|
||||||
* [新都心(Neet Shin)](mailto:nucx@dio-vox.com)
|
* [rinsuki](https://github.com/rinsuki)
|
||||||
* [cygnan](https://github.com/cygnan)
|
* [cygnan](https://github.com/cygnan)
|
||||||
* [Awea](https://github.com/Awea)
|
* [Awea](https://github.com/Awea)
|
||||||
* [halcy](https://github.com/halcy)
|
* [halcy](https://github.com/halcy)
|
||||||
* [naaaaaaaaaaaf](https://github.com/naaaaaaaaaaaf)
|
* [bounshi](https://github.com/bounshi)
|
||||||
* [NecroTechno](https://github.com/NecroTechno)
|
|
||||||
* [8398a7](https://github.com/8398a7)
|
* [8398a7](https://github.com/8398a7)
|
||||||
* [857b](https://github.com/857b)
|
* [857b](https://github.com/857b)
|
||||||
* [insom](https://github.com/insom)
|
|
||||||
* [Aditoo17](https://github.com/Aditoo17)
|
|
||||||
* [unascribed](https://github.com/unascribed)
|
* [unascribed](https://github.com/unascribed)
|
||||||
* [Aguay-val](https://github.com/Aguay-val)
|
* [Aguay-val](https://github.com/Aguay-val)
|
||||||
* [Akihiko Odaki](mailto:nekomanma@pixiv.co.jp)
|
|
||||||
* [knu](https://github.com/knu)
|
* [knu](https://github.com/knu)
|
||||||
* [h3poteto](https://github.com/h3poteto)
|
|
||||||
* [unleashed](https://github.com/unleashed)
|
|
||||||
* [alxrcs](https://github.com/alxrcs)
|
* [alxrcs](https://github.com/alxrcs)
|
||||||
* [console-cowboy](https://github.com/console-cowboy)
|
* [console-cowboy](https://github.com/console-cowboy)
|
||||||
* [pointlessone](https://github.com/pointlessone)
|
* [pointlessone](https://github.com/pointlessone)
|
||||||
* [a2](https://github.com/a2)
|
* [a2](https://github.com/a2)
|
||||||
* [0xa](https://github.com/0xa)
|
* [0xa](https://github.com/0xa)
|
||||||
* [palindromordnilap](https://github.com/palindromordnilap)
|
|
||||||
* [virtualpain](https://github.com/virtualpain)
|
* [virtualpain](https://github.com/virtualpain)
|
||||||
* [sapphirus](https://github.com/sapphirus)
|
* [sapphirus](https://github.com/sapphirus)
|
||||||
* [amandavisconti](https://github.com/amandavisconti)
|
* [amandavisconti](https://github.com/amandavisconti)
|
||||||
* [ameliavoncat](https://github.com/ameliavoncat)
|
* [ameliavoncat](https://github.com/ameliavoncat)
|
||||||
* [ilpianista](https://github.com/ilpianista)
|
* [ilpianista](https://github.com/ilpianista)
|
||||||
* [Andreas Drop](mailto:andy@remline.de)
|
* [andydrop](https://github.com/andydrop)
|
||||||
* [andi1984](https://github.com/andi1984)
|
|
||||||
* [schas002](https://github.com/schas002)
|
* [schas002](https://github.com/schas002)
|
||||||
* [abackstrom](https://github.com/abackstrom)
|
|
||||||
* [jumbosushi](https://github.com/jumbosushi)
|
* [jumbosushi](https://github.com/jumbosushi)
|
||||||
* [ayumin](https://github.com/ayumin)
|
* [ayumin](https://github.com/ayumin)
|
||||||
* [BaptisteGelez](https://github.com/BaptisteGelez)
|
* [BaptisteGelez](https://github.com/BaptisteGelez)
|
||||||
* [bzg](https://github.com/bzg)
|
* [bzg](https://github.com/bzg)
|
||||||
* [BenLubar](https://github.com/BenLubar)
|
|
||||||
* [benediktg](https://github.com/benediktg)
|
* [benediktg](https://github.com/benediktg)
|
||||||
* [blakebarnett](https://github.com/blakebarnett)
|
* [blakebarnett](https://github.com/blakebarnett)
|
||||||
* [bradj](https://github.com/bradj)
|
* [bradj](https://github.com/bradj)
|
||||||
* [brycied00d](https://github.com/brycied00d)
|
* [brycied00d](https://github.com/brycied00d)
|
||||||
* [carlosjs23](https://github.com/carlosjs23)
|
* [carlosjs23](https://github.com/carlosjs23)
|
||||||
* [cgxxx](https://github.com/cgxxx)
|
* [cgxxx](https://github.com/cgxxx)
|
||||||
* [kibitan](https://github.com/kibitan)
|
|
||||||
* [chrisheninger](https://github.com/chrisheninger)
|
* [chrisheninger](https://github.com/chrisheninger)
|
||||||
* [chris-martin](https://github.com/chris-martin)
|
* [chris-martin](https://github.com/chris-martin)
|
||||||
* [DoubleMalt](https://github.com/DoubleMalt)
|
* [DoubleMalt](https://github.com/DoubleMalt)
|
||||||
|
@ -315,33 +259,22 @@ and provided thanks to the work of the following contributors:
|
||||||
* [chriswk](https://github.com/chriswk)
|
* [chriswk](https://github.com/chriswk)
|
||||||
* [csu](https://github.com/csu)
|
* [csu](https://github.com/csu)
|
||||||
* [kklleemm](https://github.com/kklleemm)
|
* [kklleemm](https://github.com/kklleemm)
|
||||||
* [colindean](https://github.com/colindean)
|
* [monsterpit-daggertooth](https://github.com/monsterpit-daggertooth)
|
||||||
* [dachinat](https://github.com/dachinat)
|
|
||||||
* [multiple-creatures](https://github.com/multiple-creatures)
|
|
||||||
* [watilde](https://github.com/watilde)
|
* [watilde](https://github.com/watilde)
|
||||||
* [daprice](https://github.com/daprice)
|
* [daprice](https://github.com/daprice)
|
||||||
* [dar5hak](https://github.com/dar5hak)
|
* [dar5hak](https://github.com/dar5hak)
|
||||||
* [kant](https://github.com/kant)
|
* [kant](https://github.com/kant)
|
||||||
* [maxolasersquad](https://github.com/maxolasersquad)
|
|
||||||
* [singingwolfboy](https://github.com/singingwolfboy)
|
* [singingwolfboy](https://github.com/singingwolfboy)
|
||||||
* [davidcelis](https://github.com/davidcelis)
|
* [davidcelis](https://github.com/davidcelis)
|
||||||
* [davefp](https://github.com/davefp)
|
|
||||||
* [yipdw](https://github.com/yipdw)
|
* [yipdw](https://github.com/yipdw)
|
||||||
* [debanshuk](https://github.com/debanshuk)
|
* [debanshuk](https://github.com/debanshuk)
|
||||||
* [Derek Lewis](mailto:derekcecillewis@gmail.com)
|
|
||||||
* [dblandin](https://github.com/dblandin)
|
* [dblandin](https://github.com/dblandin)
|
||||||
* [Drew Gates](mailto:aranaur@users.noreply.github.com)
|
* [aranaur](https://github.com/aranaur)
|
||||||
* [dtschust](https://github.com/dtschust)
|
|
||||||
* [Dryusdan](https://github.com/Dryusdan)
|
|
||||||
* [eai04191](https://github.com/eai04191)
|
|
||||||
* [d3vgru](https://github.com/d3vgru)
|
* [d3vgru](https://github.com/d3vgru)
|
||||||
* [Elizafox](https://github.com/Elizafox)
|
* [Elizafox](https://github.com/Elizafox)
|
||||||
* [ericblade](https://github.com/ericblade)
|
* [ericblade](https://github.com/ericblade)
|
||||||
* [mikoim](https://github.com/mikoim)
|
* [mikoim](https://github.com/mikoim)
|
||||||
* [espenronnevik](https://github.com/espenronnevik)
|
|
||||||
* [Finariel](https://github.com/Finariel)
|
|
||||||
* [siuying](https://github.com/siuying)
|
* [siuying](https://github.com/siuying)
|
||||||
* [GenbuHase](https://github.com/GenbuHase)
|
|
||||||
* [hattori6789](https://github.com/hattori6789)
|
* [hattori6789](https://github.com/hattori6789)
|
||||||
* [algernon](https://github.com/algernon)
|
* [algernon](https://github.com/algernon)
|
||||||
* [Fastbyte01](https://github.com/Fastbyte01)
|
* [Fastbyte01](https://github.com/Fastbyte01)
|
||||||
|
@ -350,62 +283,52 @@ and provided thanks to the work of the following contributors:
|
||||||
* [Fiaxhs](https://github.com/Fiaxhs)
|
* [Fiaxhs](https://github.com/Fiaxhs)
|
||||||
* [reedcourty](https://github.com/reedcourty)
|
* [reedcourty](https://github.com/reedcourty)
|
||||||
* [anneau](https://github.com/anneau)
|
* [anneau](https://github.com/anneau)
|
||||||
* [lanodan](https://github.com/lanodan)
|
|
||||||
* [Harmon758](https://github.com/Harmon758)
|
|
||||||
* [HellPie](https://github.com/HellPie)
|
* [HellPie](https://github.com/HellPie)
|
||||||
* [Habu-Kagumba](https://github.com/Habu-Kagumba)
|
* [Habu-Kagumba](https://github.com/Habu-Kagumba)
|
||||||
|
* [hinaloe](https://github.com/hinaloe)
|
||||||
* [suzukaze](https://github.com/suzukaze)
|
* [suzukaze](https://github.com/suzukaze)
|
||||||
* [Hiromi-Kai](https://github.com/Hiromi-Kai)
|
* [Hiromi-Kai](https://github.com/Hiromi-Kai)
|
||||||
* [hishamhm](https://github.com/hishamhm)
|
|
||||||
* [musashino205](https://github.com/musashino205)
|
* [musashino205](https://github.com/musashino205)
|
||||||
* [iwaim](https://github.com/iwaim)
|
* [iwaim](https://github.com/iwaim)
|
||||||
* [valrus](https://github.com/valrus)
|
* [valrus](https://github.com/valrus)
|
||||||
* [IMcD23](https://github.com/IMcD23)
|
* [IMcD23](https://github.com/IMcD23)
|
||||||
* [yi0713](https://github.com/yi0713)
|
* [yi0713](https://github.com/yi0713)
|
||||||
|
* [immae](https://github.com/immae)
|
||||||
* [iblech](https://github.com/iblech)
|
* [iblech](https://github.com/iblech)
|
||||||
* [usbsnowcrash](https://github.com/usbsnowcrash)
|
|
||||||
* [jack-michaud](https://github.com/jack-michaud)
|
* [jack-michaud](https://github.com/jack-michaud)
|
||||||
* [Floppy](https://github.com/Floppy)
|
* [Floppy](https://github.com/Floppy)
|
||||||
* [loomchild](https://github.com/loomchild)
|
* [loomchild](https://github.com/loomchild)
|
||||||
* [jenkr55](https://github.com/jenkr55)
|
* [docjkl](https://github.com/docjkl)
|
||||||
* [press5](https://github.com/press5)
|
|
||||||
* [TrollDecker](https://github.com/TrollDecker)
|
* [TrollDecker](https://github.com/TrollDecker)
|
||||||
* [jmontane](https://github.com/jmontane)
|
* [jmontane](https://github.com/jmontane)
|
||||||
* [jonathanklee](https://github.com/jonathanklee)
|
* [jonathanklee](https://github.com/jonathanklee)
|
||||||
* [jguerder](https://github.com/jguerder)
|
* [jguerder](https://github.com/jguerder)
|
||||||
* [Jehops](https://github.com/Jehops)
|
* [Jehops](https://github.com/Jehops)
|
||||||
* [joshuap](https://github.com/joshuap)
|
* [joshuap](https://github.com/joshuap)
|
||||||
* [YuleZ](https://github.com/YuleZ)
|
|
||||||
* [Tiwy57](https://github.com/Tiwy57)
|
* [Tiwy57](https://github.com/Tiwy57)
|
||||||
* [xuv](https://github.com/xuv)
|
* [xuv](https://github.com/xuv)
|
||||||
* [Jnsll](https://github.com/Jnsll)
|
* [Jnsll](https://github.com/Jnsll)
|
||||||
* [j0k3r](https://github.com/j0k3r)
|
* [j0k3r](https://github.com/j0k3r)
|
||||||
* [KEINOS](https://github.com/KEINOS)
|
* [KEINOS](https://github.com/KEINOS)
|
||||||
* [futoase](https://github.com/futoase)
|
* [futoase](https://github.com/futoase)
|
||||||
* [Pneumaticat](https://github.com/Pneumaticat)
|
* [abjectio](https://github.com/abjectio)
|
||||||
* [Kit Redgrave](mailto:qwertyitis@gmail.com)
|
|
||||||
* [Knut Erik](mailto:abjectio@users.noreply.github.com)
|
|
||||||
* [mkody](https://github.com/mkody)
|
* [mkody](https://github.com/mkody)
|
||||||
|
* [connyduck](https://github.com/connyduck)
|
||||||
* [k0ta0uchi](https://github.com/k0ta0uchi)
|
* [k0ta0uchi](https://github.com/k0ta0uchi)
|
||||||
* [KrzysiekJ](https://github.com/KrzysiekJ)
|
* [KrzysiekJ](https://github.com/KrzysiekJ)
|
||||||
* [leowzukw](https://github.com/leowzukw)
|
* [leowzukw](https://github.com/leowzukw)
|
||||||
* [lmorchard](https://github.com/lmorchard)
|
* [lmorchard](https://github.com/lmorchard)
|
||||||
* [Tak](https://github.com/Tak)
|
|
||||||
* [cacheflow](https://github.com/cacheflow)
|
* [cacheflow](https://github.com/cacheflow)
|
||||||
* [ldidry](https://github.com/ldidry)
|
* [ldidry](https://github.com/ldidry)
|
||||||
* [jemus42](https://github.com/jemus42)
|
* [jemus42](https://github.com/jemus42)
|
||||||
* [lfuelling](https://github.com/lfuelling)
|
* [lfuelling](https://github.com/lfuelling)
|
||||||
* [Grabacr07](https://github.com/Grabacr07)
|
* [Grabacr07](https://github.com/Grabacr07)
|
||||||
* [mistermantas](https://github.com/mistermantas)
|
* [mistermantas](https://github.com/mistermantas)
|
||||||
* [mareklach](https://github.com/mareklach)
|
|
||||||
* [wirehack7](https://github.com/wirehack7)
|
* [wirehack7](https://github.com/wirehack7)
|
||||||
* [martymcguire](https://github.com/martymcguire)
|
|
||||||
* [marvinkopf](https://github.com/marvinkopf)
|
* [marvinkopf](https://github.com/marvinkopf)
|
||||||
* [otsune](https://github.com/otsune)
|
* [otsune](https://github.com/otsune)
|
||||||
* [Mathias B](mailto:10813340+mathias-b@users.noreply.github.com)
|
* [m-blc](https://github.com/m-blc)
|
||||||
* [matt-auckland](https://github.com/matt-auckland)
|
* [matt-auckland](https://github.com/matt-auckland)
|
||||||
* [webroo](https://github.com/webroo)
|
|
||||||
* [matthiasbeyer](https://github.com/matthiasbeyer)
|
|
||||||
* [mattjmattj](https://github.com/mattjmattj)
|
* [mattjmattj](https://github.com/mattjmattj)
|
||||||
* [mtparet](https://github.com/mtparet)
|
* [mtparet](https://github.com/mtparet)
|
||||||
* [maximeborges](https://github.com/maximeborges)
|
* [maximeborges](https://github.com/maximeborges)
|
||||||
|
@ -413,20 +336,16 @@ and provided thanks to the work of the following contributors:
|
||||||
* [michaeljdeeb](https://github.com/michaeljdeeb)
|
* [michaeljdeeb](https://github.com/michaeljdeeb)
|
||||||
* [Themimitoof](https://github.com/Themimitoof)
|
* [Themimitoof](https://github.com/Themimitoof)
|
||||||
* [cyweo](https://github.com/cyweo)
|
* [cyweo](https://github.com/cyweo)
|
||||||
* [Midgard](mailto:m1dgard@users.noreply.github.com)
|
* [M1dgard](https://github.com/M1dgard)
|
||||||
* [mike-burns](https://github.com/mike-burns)
|
* [mike-burns](https://github.com/mike-burns)
|
||||||
* [verymilan](https://github.com/verymilan)
|
* [verymilan](https://github.com/verymilan)
|
||||||
* [milmazz](https://github.com/milmazz)
|
* [milmazz](https://github.com/milmazz)
|
||||||
* [premist](https://github.com/premist)
|
|
||||||
* [Mnkai](https://github.com/Mnkai)
|
* [Mnkai](https://github.com/Mnkai)
|
||||||
* [mitchhentges](https://github.com/mitchhentges)
|
* [mitchhentges](https://github.com/mitchhentges)
|
||||||
* [moritzheiber](https://github.com/moritzheiber)
|
* [moritzheiber](https://github.com/moritzheiber)
|
||||||
* [mouse-reeve](https://github.com/mouse-reeve)
|
* [mouse-reeve](https://github.com/mouse-reeve)
|
||||||
* [Mozinet-fr](https://github.com/Mozinet-fr)
|
|
||||||
* [lae](https://github.com/lae)
|
* [lae](https://github.com/lae)
|
||||||
* [Nanamachi](https://github.com/Nanamachi)
|
* [Nanamachi](https://github.com/Nanamachi)
|
||||||
* [orinthe](https://github.com/orinthe)
|
|
||||||
* [Dar13](https://github.com/Dar13)
|
|
||||||
* [ngerakines](https://github.com/ngerakines)
|
* [ngerakines](https://github.com/ngerakines)
|
||||||
* [vonneudeck](https://github.com/vonneudeck)
|
* [vonneudeck](https://github.com/vonneudeck)
|
||||||
* [Ninetailed](https://github.com/Ninetailed)
|
* [Ninetailed](https://github.com/Ninetailed)
|
||||||
|
@ -436,23 +355,18 @@ and provided thanks to the work of the following contributors:
|
||||||
* [norayr](https://github.com/norayr)
|
* [norayr](https://github.com/norayr)
|
||||||
* [joyeusenoelle](https://github.com/joyeusenoelle)
|
* [joyeusenoelle](https://github.com/joyeusenoelle)
|
||||||
* [OlivierNicole](https://github.com/OlivierNicole)
|
* [OlivierNicole](https://github.com/OlivierNicole)
|
||||||
* [noppa](https://github.com/noppa)
|
|
||||||
* [Otakan951](https://github.com/Otakan951)
|
* [Otakan951](https://github.com/Otakan951)
|
||||||
* [fahy](https://github.com/fahy)
|
* [fahy](https://github.com/fahy)
|
||||||
* [PatrickRWells](https://github.com/PatrickRWells)
|
|
||||||
* [Pangoraw](https://github.com/Pangoraw)
|
* [Pangoraw](https://github.com/Pangoraw)
|
||||||
|
* [pwoolcoc](https://github.com/pwoolcoc)
|
||||||
* [peterkeen](https://github.com/peterkeen)
|
* [peterkeen](https://github.com/peterkeen)
|
||||||
* [pgate](https://github.com/pgate)
|
* [petzah](https://github.com/petzah)
|
||||||
* [remram44](https://github.com/remram44)
|
* [ignisf](https://github.com/ignisf)
|
||||||
* [retokromer](https://github.com/retokromer)
|
|
||||||
* [rfwatson](https://github.com/rfwatson)
|
* [rfwatson](https://github.com/rfwatson)
|
||||||
* [rfreebern](https://github.com/rfreebern)
|
* [rfreebern](https://github.com/rfreebern)
|
||||||
* [Ryan Wade](mailto:ryan.wade@protonmail.com)
|
|
||||||
* [sylph01](https://github.com/sylph01)
|
* [sylph01](https://github.com/sylph01)
|
||||||
* [S-H-GAMELINKS](https://github.com/S-H-GAMELINKS)
|
|
||||||
* [staticsafe](https://github.com/staticsafe)
|
* [staticsafe](https://github.com/staticsafe)
|
||||||
* [snwh](https://github.com/snwh)
|
* [snwh](https://github.com/snwh)
|
||||||
* [sts10](https://github.com/sts10)
|
|
||||||
* [skoji](https://github.com/skoji)
|
* [skoji](https://github.com/skoji)
|
||||||
* [ScienJus](https://github.com/ScienJus)
|
* [ScienJus](https://github.com/ScienJus)
|
||||||
* [larkinscott](https://github.com/larkinscott)
|
* [larkinscott](https://github.com/larkinscott)
|
||||||
|
@ -464,103 +378,73 @@ and provided thanks to the work of the following contributors:
|
||||||
* [ernix](https://github.com/ernix)
|
* [ernix](https://github.com/ernix)
|
||||||
* [rosylilly](https://github.com/rosylilly)
|
* [rosylilly](https://github.com/rosylilly)
|
||||||
* [shouko](https://github.com/shouko)
|
* [shouko](https://github.com/shouko)
|
||||||
* [Sina Mashek](mailto:sina@mashek.xyz)
|
|
||||||
* [sossii](https://github.com/sossii)
|
* [sossii](https://github.com/sossii)
|
||||||
* [Spanky](mailto:2788886+spankyworks@users.noreply.github.com)
|
* [StefOfficiel](https://github.com/StefOfficiel)
|
||||||
* [StefOfficiel](mailto:pichard.stephane@free.fr)
|
* [svetlik](https://github.com/svetlik)
|
||||||
* [Svetlozar Todorov](mailto:svetlik@users.noreply.github.com)
|
* [dereckson](https://github.com/dereckson)
|
||||||
* [Sébastien Santoro](mailto:dereckson@espace-win.org)
|
* [theboss](https://github.com/theboss)
|
||||||
* [Tad Thorley](mailto:phaedryx@users.noreply.github.com)
|
* [takp](https://github.com/takp)
|
||||||
* [Takayoshi Nishida](mailto:takayoshi.nishida@gmail.com)
|
* [tkusano](https://github.com/tkusano)
|
||||||
* [Takayuki KUSANO](mailto:github@tkusano.jp)
|
* [TheInventrix](https://github.com/TheInventrix)
|
||||||
* [TakesxiSximada](mailto:takesxi.sximada@gmail.com)
|
* [shug0](https://github.com/shug0)
|
||||||
* [TheInventrix](mailto:theinventrix@users.noreply.github.com)
|
* [Fortyseven](https://github.com/Fortyseven)
|
||||||
* [Thomas Alberola](mailto:thomas@needacoffee.fr)
|
* [tobypinder](https://github.com/tobypinder)
|
||||||
* [Toby Deshane](mailto:fortyseven@users.noreply.github.com)
|
* [tomosm](https://github.com/tomosm)
|
||||||
* [Toby Pinder](mailto:gigitrix@gmail.com)
|
* [TomoyaShibata](https://github.com/TomoyaShibata)
|
||||||
* [Tomonori Murakami](mailto:crosslife777@gmail.com)
|
* [TrashMacNugget](https://github.com/TrashMacNugget)
|
||||||
* [TomoyaShibata](mailto:wind.of.hometown@gmail.com)
|
* [treyssatvincent](https://github.com/treyssatvincent)
|
||||||
* [Treyssat-Vincent Nino](mailto:treyssatvincent@users.noreply.github.com)
|
* [optikfluffel](https://github.com/optikfluffel)
|
||||||
* [Udo Kramer](mailto:optik@fluffel.io)
|
* [vmincev](https://github.com/vmincev)
|
||||||
* [Una](mailto:una@unascribed.com)
|
* [waldyrious](https://github.com/waldyrious)
|
||||||
* [Ushitora Anqou](mailto:ushitora_anqou@yahoo.co.jp)
|
* [tahnok](https://github.com/tahnok)
|
||||||
* [Valentin Lorentz](mailto:progval+git@progval.net)
|
* [YDrogen](https://github.com/YDrogen)
|
||||||
* [Vladimir Mincev](mailto:vladimir@canicinteractive.com)
|
* [YOSHIOKAEiichiro](https://github.com/YOSHIOKAEiichiro)
|
||||||
* [Waldir Pimenta](mailto:waldyrious@gmail.com)
|
* [S-YOU](https://github.com/S-YOU)
|
||||||
* [Wesley Ellis](mailto:tahnok@gmail.com)
|
* [YaQ00](https://github.com/YaQ00)
|
||||||
* [Wiktor](mailto:wiktor@metacode.biz)
|
* [yanakend](https://github.com/yanakend)
|
||||||
* [Wonderfall](mailto:wonderfall@schrodinger.io)
|
* [orzFly](https://github.com/orzFly)
|
||||||
* [YDrogen](mailto:ydrogen45@gmail.com)
|
* [chansuke](https://github.com/chansuke)
|
||||||
* [YMHuang](mailto:ymhuang@fmbase.tw)
|
* [yuntan](https://github.com/yuntan)
|
||||||
* [YOSHIOKA Eiichiro](mailto:yoshioka.eiichiro@gmail.com)
|
* [LogicalDash](https://github.com/LogicalDash)
|
||||||
* [YOU](mailto:stackexchange.you@gmail.com)
|
* [ZiiX](https://github.com/ZiiX)
|
||||||
* [YaQ](mailto:i_k_o_m_a_7@yahoo.co.jp)
|
* [benklop](https://github.com/benklop)
|
||||||
* [Yanaken](mailto:yanakend@gmail.com)
|
* [caasi](https://github.com/caasi)
|
||||||
* [Yann Klis](mailto:yann.klis@gmail.com)
|
* [caesarologia](https://github.com/caesarologia)
|
||||||
* [Yeechan Lu](mailto:wz.bluesnow@gmail.com)
|
* [chrolis](https://github.com/chrolis)
|
||||||
* [Yusuke Abe](mailto:moonset20@gmail.com)
|
* [cormojs](https://github.com/cormojs)
|
||||||
* [Zachary Spector](mailto:logicaldash@gmail.com)
|
* [cpsdqs](https://github.com/cpsdqs)
|
||||||
* [ZiiX](mailto:ziix@users.noreply.github.com)
|
* [d0p1s4m4](https://github.com/d0p1s4m4)
|
||||||
* [asria-jp](mailto:is@alicematic.com)
|
* [evilny0](https://github.com/evilny0)
|
||||||
* [ava](mailto:vladooku@users.noreply.github.com)
|
* [febrezo](https://github.com/febrezo)
|
||||||
* [benklop](mailto:benklop@gmail.com)
|
* [fsubal](https://github.com/fsubal)
|
||||||
* [bsky](mailto:git@imbsky.net)
|
* [dikky1218](https://github.com/dikky1218)
|
||||||
* [caesarologia](mailto:lopesgemelli.1@gmail.com)
|
* [gentarok](https://github.com/gentarok)
|
||||||
* [cbayerlein](mailto:c.bayerlein@gmail.com)
|
* [hakoai](https://github.com/hakoai)
|
||||||
* [chrolis](mailto:chrolis@users.noreply.github.com)
|
* [chaosbunker](https://github.com/chaosbunker)
|
||||||
* [cormo](mailto:cormorant2+github@gmail.com)
|
* [isati](https://github.com/isati)
|
||||||
* [d0p1](mailto:dopi-sama@hush.com)
|
* [jkap](https://github.com/jkap)
|
||||||
* [evilny0](mailto:evilny0@moomoocamp.net)
|
* [jirayudech](https://github.com/jirayudech)
|
||||||
* [febrezo](mailto:felixbrezo@gmail.com)
|
* [jukper](https://github.com/jukper)
|
||||||
* [fsubal](mailto:fsubal@users.noreply.github.com)
|
* [karlyeurl](https://github.com/karlyeurl)
|
||||||
* [fusshi-](mailto:dikky1218@users.noreply.github.com)
|
* [kedamaDQ](https://github.com/kedamaDQ)
|
||||||
* [gentaro](mailto:gentaroooo@gmail.com)
|
* [kuro5hin](https://github.com/kuro5hin)
|
||||||
* [hakoai](mailto:hk--76@qa2.so-net.ne.jp)
|
* [maxypy](https://github.com/maxypy)
|
||||||
* [haosbvnker](mailto:github@chaosbunker.com)
|
* [marcus-herrmann](https://github.com/marcus-herrmann)
|
||||||
* [isati](mailto:phil@juchnowi.cz)
|
* [mshrtkch](https://github.com/mshrtkch)
|
||||||
* [jacob](mailto:jacobherringtondeveloper@gmail.com)
|
* [muan](https://github.com/muan)
|
||||||
* [jenn kaplan](mailto:me@jkap.io)
|
* [rch850](https://github.com/rch850)
|
||||||
* [jirayudech](mailto:jirayudech@gmail.com)
|
* [roikale](https://github.com/roikale)
|
||||||
* [jooops](mailto:joops@autistici.org)
|
* [rysiekpl](https://github.com/rysiekpl)
|
||||||
* [jukper](mailto:jukkaperanto@gmail.com)
|
* [saturday06](https://github.com/saturday06)
|
||||||
* [jumoru](mailto:jumoru@mailbox.org)
|
* [scriptjunkie](https://github.com/scriptjunkie)
|
||||||
* [karlyeurl](mailto:karl.yeurl@gmail.com)
|
* [seekr](https://github.com/seekr)
|
||||||
* [kedama](mailto:32974885+kedamadq@users.noreply.github.com)
|
* [syui](https://github.com/syui)
|
||||||
* [kuro5hin](mailto:rusty@kuro5hin.org)
|
* [tackeyy](https://github.com/tackeyy)
|
||||||
* [luzpaz](mailto:luzpaz@users.noreply.github.com)
|
* [tmyt](https://github.com/tmyt)
|
||||||
* [maxypy](mailto:maxime@mpigou.fr)
|
* [utam0k](https://github.com/utam0k)
|
||||||
* [mhe](mailto:mail@marcus-herrmann.com)
|
* [vpzomtrrfrt](https://github.com/vpzomtrrfrt)
|
||||||
* [mimikun](mailto:dzdzble_effort_311@outlook.jp)
|
* [walfie](https://github.com/walfie)
|
||||||
* [mshrtkch](mailto:mshrtkch@users.noreply.github.com)
|
* [y-temp4](https://github.com/y-temp4)
|
||||||
* [muan](mailto:muan@github.com)
|
* [ymmtmdk](https://github.com/ymmtmdk)
|
||||||
* [neetshin](mailto:neetshin@neetsh.in)
|
|
||||||
* [nightpool](mailto:nightpool@users.noreply.github.com)
|
|
||||||
* [rch850](mailto:rich850@gmail.com)
|
|
||||||
* [roikale](mailto:roikale@users.noreply.github.com)
|
|
||||||
* [rysiekpl](mailto:rysiek@hackerspace.pl)
|
|
||||||
* [saturday06](mailto:dyob@lunaport.net)
|
|
||||||
* [scriptjunkie](mailto:scriptjunkie@scriptjunkie.us)
|
|
||||||
* [seekr](mailto:mario.drs@gmail.com)
|
|
||||||
* [sundevour](mailto:31990469+sundevour@users.noreply.github.com)
|
|
||||||
* [syui](mailto:syui@users.noreply.github.com)
|
|
||||||
* [tackeyy](mailto:mailto.takita.yusuke@gmail.com)
|
|
||||||
* [tateisu](mailto:tateisu@gmail.com)
|
|
||||||
* [tmyt](mailto:shigure@refy.net)
|
|
||||||
* [trevDev()](mailto:trev@trevdev.ca)
|
|
||||||
* [utam0k](mailto:k0ma@utam0k.jp)
|
|
||||||
* [vpzomtrrfrt](mailto:vpzomtrrfrt@gmail.com)
|
|
||||||
* [walfie](mailto:walfington@gmail.com)
|
|
||||||
* [y-temp4](mailto:y.temp4@gmail.com)
|
|
||||||
* [ymmtmdk](mailto:ymmtmdk@gmail.com)
|
|
||||||
* [yoshipc](mailto:yoooo@yoshipc.net)
|
|
||||||
* [Özcan Zafer AYAN](mailto:ozcanzaferayan@gmail.com)
|
|
||||||
* [ばん](mailto:detteiu0321@gmail.com)
|
|
||||||
* [みたらしだんご](mailto:mitarashidango@users.noreply.github.com)
|
|
||||||
* [りんすき](mailto:6533808+rinsuki@users.noreply.github.com)
|
|
||||||
* [ヨイツの賢狼ホロ | 3rd style](mailto:horo@yoitsu.moe)
|
|
||||||
* [猫吸血鬼ディフリス / 猫ロキP](mailto:deflis@gmail.com)
|
|
||||||
* [艮 鮟鱇](mailto:ushitora_anqou@yahoo.co.jp)
|
|
||||||
* [西小倉宏信](mailto:nishiko@mindia.jp)
|
|
||||||
* [雨宮美羽](mailto:k737566@gmail.com)
|
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
19
Aptfile
|
@ -5,25 +5,6 @@ libidn11
|
||||||
libidn11-dev
|
libidn11-dev
|
||||||
libpq-dev
|
libpq-dev
|
||||||
libprotobuf-dev
|
libprotobuf-dev
|
||||||
libssl-dev
|
|
||||||
libxdamage1
|
libxdamage1
|
||||||
libxfixes3
|
libxfixes3
|
||||||
protobuf-compiler
|
protobuf-compiler
|
||||||
zlib1g-dev
|
|
||||||
libcairo2
|
|
||||||
libcroco3
|
|
||||||
libdatrie1
|
|
||||||
libgdk-pixbuf2.0-0
|
|
||||||
libgraphite2-3
|
|
||||||
libharfbuzz0b
|
|
||||||
libpango-1.0-0
|
|
||||||
libpangocairo-1.0-0
|
|
||||||
libpangoft2-1.0-0
|
|
||||||
libpixman-1-0
|
|
||||||
librsvg2-2
|
|
||||||
libthai-data
|
|
||||||
libthai0
|
|
||||||
libvpx5
|
|
||||||
libxcb-render0
|
|
||||||
libxcb-shm0
|
|
||||||
libxrender1
|
|
||||||
|
|
134
CHANGELOG.md
|
@ -1,134 +0,0 @@
|
||||||
Changelog
|
|
||||||
=========
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
## [2.6.1] - 2018-10-30
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix resolving resources by URL not working due to a regression in #9132 (#9171)
|
|
||||||
- Fix reducer error in web UI when a conversation has no last status (#9173)
|
|
||||||
|
|
||||||
## [2.6.0] - 2018-10-30
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Add link ownership verification (#8703)
|
|
||||||
- Add conversations API (#8832)
|
|
||||||
- Add limit for the number of people that can be followed from one account (#8807)
|
|
||||||
- Add admin setting to customize mascot (#8766)
|
|
||||||
- Add support for more granular ActivityPub audiences from other software, i.e. circles (#8950, #9093, #9150)
|
|
||||||
- Add option to block all reports from a domain (#8830)
|
|
||||||
- Add user preference to always expand toots marked with content warnings (#8762)
|
|
||||||
- Add user preference to always hide all media (#8569)
|
|
||||||
- Add `force_login` param to OAuth authorize page (#8655)
|
|
||||||
- Add `tootctl accounts backup` (#8642, #8811)
|
|
||||||
- Add `tootctl accounts create` (#8642, #8811)
|
|
||||||
- Add `tootctl accounts cull` (#8642, #8811)
|
|
||||||
- Add `tootctl accounts delete` (#8642, #8811)
|
|
||||||
- Add `tootctl accounts modify` (#8642, #8811)
|
|
||||||
- Add `tootctl accounts refresh` (#8642, #8811)
|
|
||||||
- Add `tootctl feeds build` (#8642, #8811)
|
|
||||||
- Add `tootctl feeds clear` (#8642, #8811)
|
|
||||||
- Add `tootctl settings registrations open` (#8642, #8811)
|
|
||||||
- Add `tootctl settings registrations close` (#8642, #8811)
|
|
||||||
- Add `min_id` param to REST API to support backwards pagination (#8736)
|
|
||||||
- Add a confirmation dialog when hitting reply and the compose box isn't empty (#8893)
|
|
||||||
- Add PostgreSQL disk space growth tracking in PGHero (#8906)
|
|
||||||
- Add button for disabling local account to report quick actions bar (#9024)
|
|
||||||
- Add Czech language (#8594)
|
|
||||||
- Add `same-site` (`lax`) attribute to cookies (#8626)
|
|
||||||
- Add support for styled scrollbars in Firefox Nightly (#8653)
|
|
||||||
- Add highlight to the active tab in web UI profiles (#8673)
|
|
||||||
- Add auto-focus for comment textarea in report modal (#8689)
|
|
||||||
- Add auto-focus for emoji picker's search field (#8688)
|
|
||||||
- Add nginx and systemd templates to `dist/` directory (#8770)
|
|
||||||
- Add support for `/.well-known/change-password` (#8828)
|
|
||||||
- Add option to override FFMPEG binary path (#8855)
|
|
||||||
- Add `dns-prefetch` tag when using different host for assets or uploads (#8942)
|
|
||||||
- Add `description` meta tag (#8941)
|
|
||||||
- Add `Content-Security-Policy` header (#8957)
|
|
||||||
- Add cache for the instance info API (#8765)
|
|
||||||
- Add suggested follows to search screen in mobile layout (#9010)
|
|
||||||
- Add CORS header to `/.well-known/*` routes (#9083)
|
|
||||||
- Add `card` attribute to statuses returned from REST API (#9120)
|
|
||||||
- Add in-stream link preview (#9120)
|
|
||||||
- Add support for ActivityPub `Page` objects (#9121)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Change forms design (#8703)
|
|
||||||
- Change reports overview to group by target account (#8674)
|
|
||||||
- Change web UI to show "read more" link on overly long in-stream statuses (#8205)
|
|
||||||
- Change design of direct messages column (#8832, #9022)
|
|
||||||
- Change home timelines to exclude DMs (#8940)
|
|
||||||
- Change list timelines to exclude all replies (#8683)
|
|
||||||
- Change admin accounts UI default sort to most recent (#8813)
|
|
||||||
- Change documentation URL in the UI (#8898)
|
|
||||||
- Change style of success and failure messages (#8973)
|
|
||||||
- Change DM filtering to always allow DMs from staff (#8993)
|
|
||||||
- Change recommended Ruby version to 2.5.3 (#9003)
|
|
||||||
- Change docker-compose default to persist volumes in current directory (#9055)
|
|
||||||
- Change character counters on edit profile page to input length limit (#9100)
|
|
||||||
- Change notification filtering to always let through messages from staff (#9152)
|
|
||||||
- Change "hide boosts from user" function also hiding notifications about boosts (#9147)
|
|
||||||
- Change CSS `detailed-status__wrapper` class actually wrap the detailed status (#8547)
|
|
||||||
|
|
||||||
### Deprecated
|
|
||||||
|
|
||||||
- `GET /api/v1/timelines/direct` → `GET /api/v1/conversations` (#8832)
|
|
||||||
- `POST /api/v1/notifications/dismiss` → `POST /api/v1/notifications/:id/dismiss` (#8905)
|
|
||||||
- `GET /api/v1/statuses/:id/card` → `card` attributed included in status (#9120)
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
- Remove "on this device" label in column push settings (#8704)
|
|
||||||
- Remove rake tasks in favour of tootctl commands (#8675)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix remote statuses using instance's default locale if no language given (#8861)
|
|
||||||
- Fix streaming API not exiting when port or socket is unavailable (#9023)
|
|
||||||
- Fix network calls being performed in database transaction in ActivityPub handler (#8951)
|
|
||||||
- Fix dropdown arrow position (#8637)
|
|
||||||
- Fix first element of dropdowns being focused even if not using keyboard (#8679)
|
|
||||||
- Fix tootctl requiring `bundle exec` invocation (#8619)
|
|
||||||
- Fix public pages not using animation preference for avatars (#8614)
|
|
||||||
- Fix OEmbed/OpenGraph cards not understanding relative URLs (#8669)
|
|
||||||
- Fix some dark emojis not having a white outline (#8597)
|
|
||||||
- Fix media description not being displayed in various media modals (#8678)
|
|
||||||
- Fix generated URLs of desktop notifications missing base URL (#8758)
|
|
||||||
- Fix RTL styles (#8764, #8767, #8823, #8897, #9005, #9007, #9018, #9021, #9145, #9146)
|
|
||||||
- Fix crash in streaming API when tag param missing (#8955)
|
|
||||||
- Fix hotkeys not working when no element is focused (#8998)
|
|
||||||
- Fix some hotkeys not working on detailed status view (#9006)
|
|
||||||
- Fix og:url on status pages (#9047)
|
|
||||||
- Fix upload option buttons only being visible on hover (#9074)
|
|
||||||
- Fix tootctl not returning exit code 1 on wrong arguments (#9094)
|
|
||||||
- Fix preview cards for appearing for profiles mentioned in toot (#6934, #9158)
|
|
||||||
- Fix local accounts sometimes being duplicated as faux-remote (#9109)
|
|
||||||
- Fix emoji search when the shortcode has multiple separators (#9124)
|
|
||||||
- Fix dropdowns sometimes being partially obscured by other elements (#9126)
|
|
||||||
- Fix cache not updating when reply/boost/favourite counters or media sensitivity update (#9119)
|
|
||||||
- Fix empty display name precedence over username in web UI (#9163)
|
|
||||||
- Fix td instead of th in sessions table header (#9162)
|
|
||||||
- Fix handling of content types with profile (#9132)
|
|
||||||
|
|
||||||
## [2.5.2] - 2018-10-12
|
|
||||||
### Security
|
|
||||||
|
|
||||||
- Fix XSS vulnerability (#8959)
|
|
||||||
|
|
||||||
## [2.5.1] - 2018-10-07
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix database migrations for PostgreSQL below 9.5 (#8903)
|
|
||||||
- Fix class autoloading issue in ActivityPub Create handler (#8820)
|
|
||||||
- Fix cache statistics not being sent via statsd when statsd enabled (#8831)
|
|
||||||
- Bump puma from 3.11.4 to 3.12.0 (#8883)
|
|
||||||
|
|
||||||
### Security
|
|
||||||
|
|
||||||
- Fix some local images not having their EXIF metadata stripped on upload (#8714)
|
|
||||||
- Fix being able to enable a disabled relay via ActivityPub Accept handler (#8864)
|
|
||||||
- Bump nokogiri from 1.8.4 to 1.8.5 (#8881)
|
|
||||||
- Fix being able to report statuses not belonging to the reported account (#8916)
|
|
|
@ -1,37 +1,56 @@
|
||||||
Contributing
|
CONTRIBUTING
|
||||||
============
|
============
|
||||||
|
|
||||||
Thank you for considering contributing to Mastodon 🐘
|
There are three ways in which you can contribute to this repository:
|
||||||
|
|
||||||
You can contribute in the following ways:
|
1. By improving the documentation
|
||||||
|
2. By working on the back-end application
|
||||||
|
3. By working on the front-end application
|
||||||
|
|
||||||
- Finding and reporting bugs
|
Choosing what to work on in a large open source project is not easy. The list of [GitHub issues](https://github.com/tootsuite/mastodon/issues) may provide some ideas, but not every feature request has been greenlit. Likewise, not every change or feature that resolves a personal itch will be merged into the main repository. Some communication ahead of time may be wise. If your addition creates a new feature or setting, or otherwise changes how things work in some substantial way, please remember to submit a correlating pull request to document your changes in the [documentation](http://github.com/tootsuite/documentation).
|
||||||
- Translating the Mastodon interface into various languages
|
|
||||||
- Contributing code to Mastodon by fixing bugs or implementing features
|
|
||||||
- Improving the documentation
|
|
||||||
|
|
||||||
## Bug reports
|
Below are the guidelines for working on pull requests:
|
||||||
|
|
||||||
Bug reports and feature suggestions can be submitted to [GitHub Issues](https://github.com/tootsuite/mastodon/issues). Please make sure that you are not submitting duplicates, and that a similar report or request has not already been resolved or rejected in the past using the search function. Please also use descriptive, concise titles.
|
## General
|
||||||
|
|
||||||
## Translations
|
- 2 spaces indentation
|
||||||
|
|
||||||
You can submit translations via [Weblate](https://weblate.joinmastodon.org/). They are periodically merged into the codebase.
|
|
||||||
|
|
||||||
[![Mastodon translation statistics by language](https://weblate.joinmastodon.org/widgets/mastodon/-/multi-auto.svg)](https://weblate.joinmastodon.org/)
|
|
||||||
|
|
||||||
## Pull requests
|
|
||||||
|
|
||||||
Please use clean, concise titles for your pull requests. We use commit squashing, so the final commit in the master branch will carry the title of the pull request.
|
|
||||||
|
|
||||||
The smaller the set of changes in the pull request is, the quicker it can be reviewed and merged. Splitting tasks into multiple smaller pull requests is often preferable.
|
|
||||||
|
|
||||||
**Pull requests that do not pass automated checks may not be reviewed**. In particular, you need to keep in mind:
|
|
||||||
|
|
||||||
- Unit and integration tests (rspec, jest)
|
|
||||||
- Code style rules (rubocop, eslint)
|
|
||||||
- Normalization of locale files (i18n-tasks)
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/docs](https://source.joinmastodon.org/mastodon/docs).
|
- No spelling mistakes
|
||||||
|
- No orthographic mistakes
|
||||||
|
- No Markdown syntax errors
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Ruby
|
||||||
|
- Node.js
|
||||||
|
- PostgreSQL
|
||||||
|
- Redis
|
||||||
|
- Nginx (optional)
|
||||||
|
|
||||||
|
## Back-end application
|
||||||
|
|
||||||
|
It is expected that you have a working development environment set up. The development environment includes [rubocop](https://github.com/bbatsov/rubocop), which checks your Ruby code for compliance with our style guide and best practices. Sublime Text, likely like other editors, has a [Rubocop plugin](https://github.com/pderichs/sublime_rubocop) that runs checks on files as you edit them. The codebase also has a test suite.
|
||||||
|
|
||||||
|
* The codebase is not perfect, at the time of writing, but it is expected that you do not introduce new code style violations
|
||||||
|
* The rspec test suite must pass
|
||||||
|
* To the extent that it is possible, verify your changes. In the best case, by adding new tests to the test suite. At the very least, by running the server or console and checking it manually
|
||||||
|
* If you are introducing new strings to the user interface, they must be using localization methods
|
||||||
|
|
||||||
|
If your code has syntax errors that won't let it run, it's a good sign that the pull request isn't ready for submission yet.
|
||||||
|
|
||||||
|
## Front-end application
|
||||||
|
|
||||||
|
It is expected that you have a working development environment set up (see back-end application section). This project includes an ESLint configuration file, with which you can lint your changes.
|
||||||
|
|
||||||
|
* Avoid grave ESLint violations
|
||||||
|
* Verify that your changes work
|
||||||
|
* If you are introducing new strings, they must be using localization methods
|
||||||
|
|
||||||
|
If the JavaScript or CSS assets won't compile due to a syntax error, it's a good sign that the pull request isn't ready for submission yet.
|
||||||
|
|
||||||
|
## Translate
|
||||||
|
|
||||||
|
You can contribute to translating Mastodon via Weblate at [weblate.joinmastodon.org](https://weblate.joinmastodon.org/).
|
||||||
|
[![Mastodon translation statistics by language](https://weblate.joinmastodon.org/widgets/mastodon/-/multi-auto.svg)](https://weblate.joinmastodon.org/)
|
||||||
|
|
25
Dockerfile
|
@ -1,5 +1,4 @@
|
||||||
FROM node:8.12.0-alpine as node
|
FROM ruby:2.4.4-alpine3.6
|
||||||
FROM ruby:2.4.5-alpine3.8
|
|
||||||
|
|
||||||
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
LABEL maintainer="https://github.com/tootsuite/mastodon" \
|
||||||
description="Your self-hosted, globally interconnected microblogging community"
|
description="Your self-hosted, globally interconnected microblogging community"
|
||||||
|
@ -12,6 +11,8 @@ ENV PATH=/mastodon/bin:$PATH \
|
||||||
RAILS_ENV=production \
|
RAILS_ENV=production \
|
||||||
NODE_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
|
||||||
|
|
||||||
|
@ -19,11 +20,6 @@ EXPOSE 3000 4000
|
||||||
|
|
||||||
WORKDIR /mastodon
|
WORKDIR /mastodon
|
||||||
|
|
||||||
COPY --from=node /usr/local/bin/node /usr/local/bin/node
|
|
||||||
COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules
|
|
||||||
COPY --from=node /usr/local/bin/npm /usr/local/bin/npm
|
|
||||||
COPY --from=node /opt/yarn-* /opt/yarn
|
|
||||||
|
|
||||||
RUN apk -U upgrade \
|
RUN apk -U upgrade \
|
||||||
&& apk add -t build-dependencies \
|
&& apk add -t build-dependencies \
|
||||||
build-base \
|
build-base \
|
||||||
|
@ -43,13 +39,20 @@ RUN apk -U upgrade \
|
||||||
imagemagick \
|
imagemagick \
|
||||||
libidn \
|
libidn \
|
||||||
libpq \
|
libpq \
|
||||||
|
nodejs \
|
||||||
|
nodejs-npm \
|
||||||
protobuf \
|
protobuf \
|
||||||
tini \
|
tini \
|
||||||
tzdata \
|
tzdata \
|
||||||
&& update-ca-certificates \
|
&& update-ca-certificates \
|
||||||
|
&& mkdir -p /tmp/src /opt \
|
||||||
|
&& wget -O yarn.tar.gz "https://github.com/yarnpkg/yarn/releases/download/v$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
|
||||||
|
&& echo "$YARN_DOWNLOAD_SHA256 *yarn.tar.gz" | sha256sum -c - \
|
||||||
|
&& tar -xzf yarn.tar.gz -C /tmp/src \
|
||||||
|
&& rm yarn.tar.gz \
|
||||||
|
&& mv /tmp/src/yarn-v$YARN_VERSION /opt/yarn \
|
||||||
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
&& ln -s /opt/yarn/bin/yarn /usr/local/bin/yarn \
|
||||||
&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
|
&& ln -s /opt/yarn/bin/yarnpkg /usr/local/bin/yarnpkg \
|
||||||
&& mkdir -p /tmp/src /opt \
|
|
||||||
&& wget -O libiconv.tar.gz "https://ftp.gnu.org/pub/gnu/libiconv/libiconv-$LIBICONV_VERSION.tar.gz" \
|
&& 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 - \
|
||||||
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
&& tar -xzf libiconv.tar.gz -C /tmp/src \
|
||||||
|
@ -66,7 +69,7 @@ COPY Gemfile Gemfile.lock package.json yarn.lock .yarnclean /mastodon/
|
||||||
|
|
||||||
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 install --pure-lockfile --ignore-engines \
|
&& yarn --pure-lockfile \
|
||||||
&& yarn cache clean
|
&& yarn cache clean
|
||||||
|
|
||||||
RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \
|
RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \
|
||||||
|
@ -77,10 +80,8 @@ COPY . /mastodon
|
||||||
|
|
||||||
RUN chown -R mastodon:mastodon /mastodon
|
RUN chown -R mastodon:mastodon /mastodon
|
||||||
|
|
||||||
VOLUME /mastodon/public/system
|
VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs
|
||||||
|
|
||||||
USER mastodon
|
USER mastodon
|
||||||
|
|
||||||
RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile
|
|
||||||
|
|
||||||
ENTRYPOINT ["/sbin/tini", "--"]
|
ENTRYPOINT ["/sbin/tini", "--"]
|
||||||
|
|
78
Gemfile
|
@ -5,36 +5,35 @@ ruby '>= 2.3.0', '< 2.6.0'
|
||||||
|
|
||||||
gem 'pkg-config', '~> 1.3'
|
gem 'pkg-config', '~> 1.3'
|
||||||
|
|
||||||
gem 'puma', '~> 3.12'
|
gem 'puma', '~> 3.11'
|
||||||
gem 'rails', '~> 5.2.1'
|
gem 'rails', '~> 5.2.0'
|
||||||
gem 'thor', '~> 0.20'
|
|
||||||
|
|
||||||
gem 'hamlit-rails', '~> 0.2'
|
gem 'hamlit-rails', '~> 0.2'
|
||||||
gem 'pg', '~> 1.1'
|
gem 'pg', '~> 1.0'
|
||||||
gem 'makara', '~> 0.4'
|
gem 'pghero', '~> 2.1'
|
||||||
gem 'pghero', '~> 2.2'
|
gem 'dotenv-rails', '~> 2.2', '< 2.3'
|
||||||
gem 'dotenv-rails', '~> 2.5'
|
|
||||||
|
|
||||||
gem 'aws-sdk-s3', '~> 1.23', require: false
|
gem 'aws-sdk-s3', '~> 1.9', require: false
|
||||||
gem 'fog-core', '<= 2.1.0'
|
gem 'fog-core', '~> 1.45'
|
||||||
gem 'fog-openstack', '~> 0.3', require: false
|
gem 'fog-local', '~> 0.5', require: false
|
||||||
|
gem 'fog-openstack', '~> 0.1', require: false
|
||||||
gem 'paperclip', '~> 6.0'
|
gem 'paperclip', '~> 6.0'
|
||||||
gem 'paperclip-av-transcoder', '~> 0.6'
|
gem 'paperclip-av-transcoder', '~> 0.6'
|
||||||
gem 'streamio-ffmpeg', '~> 3.0'
|
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', require: false
|
gem 'bootsnap', '~> 1.3'
|
||||||
gem 'browser'
|
gem 'browser'
|
||||||
gem 'charlock_holmes', '~> 0.7.6'
|
gem 'charlock_holmes', '~> 0.7.6'
|
||||||
gem 'iso-639'
|
gem 'iso-639'
|
||||||
gem 'chewy', '~> 5.0'
|
gem 'chewy', '~> 5.0'
|
||||||
gem 'cld3', '~> 3.2.0'
|
gem 'cld3', '~> 3.2.0'
|
||||||
gem 'devise', '~> 4.5'
|
gem 'devise', '~> 4.4'
|
||||||
gem 'devise-two-factor', '~> 3.0'
|
gem 'devise-two-factor', '~> 3.0'
|
||||||
|
|
||||||
group :pam_authentication, optional: true do
|
group :pam_authentication, optional: true do
|
||||||
gem 'devise_pam_authenticatable2', '~> 9.2'
|
gem 'devise_pam_authenticatable2', '~> 9.1'
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'net-ldap', '~> 0.10'
|
gem 'net-ldap', '~> 0.10'
|
||||||
|
@ -42,51 +41,52 @@ gem 'omniauth-cas', '~> 1.1'
|
||||||
gem 'omniauth-saml', '~> 1.10'
|
gem 'omniauth-saml', '~> 1.10'
|
||||||
gem 'omniauth', '~> 1.2'
|
gem 'omniauth', '~> 1.2'
|
||||||
|
|
||||||
gem 'doorkeeper', '~> 5.0'
|
gem 'doorkeeper', '~> 4.4'
|
||||||
gem 'fast_blank', '~> 1.0'
|
gem 'fast_blank', '~> 1.0'
|
||||||
gem 'fastimage'
|
gem 'fastimage'
|
||||||
gem 'goldfinger', '~> 2.1'
|
gem 'goldfinger', '~> 2.1'
|
||||||
gem 'hiredis', '~> 0.6'
|
gem 'hiredis', '~> 0.6'
|
||||||
gem 'redis-namespace', '~> 1.5'
|
gem 'redis-namespace', '~> 1.5'
|
||||||
gem 'htmlentities', '~> 4.3'
|
gem 'htmlentities', '~> 4.3'
|
||||||
gem 'http', '~> 3.3'
|
gem 'http', '~> 3.2'
|
||||||
gem 'http_accept_language', '~> 2.1'
|
gem 'http_accept_language', '~> 2.1'
|
||||||
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2'
|
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2'
|
||||||
gem 'httplog', '~> 1.1'
|
gem 'httplog', '~> 1.0'
|
||||||
gem 'idn-ruby', require: 'idn'
|
gem 'idn-ruby', require: 'idn'
|
||||||
gem 'kaminari', '~> 1.1'
|
gem 'kaminari', '~> 1.1'
|
||||||
gem 'link_header', '~> 0.0'
|
gem 'link_header', '~> 0.0'
|
||||||
gem 'mime-types', '~> 3.2', require: 'mime/types/columnar'
|
gem 'mime-types', '~> 3.1', require: 'mime/types/columnar'
|
||||||
gem 'nokogiri', '~> 1.8'
|
gem 'nokogiri', '~> 1.8'
|
||||||
gem 'nsa', '~> 0.2'
|
gem 'nsa', '~> 0.2'
|
||||||
gem 'oj', '~> 3.7'
|
gem 'oj', '~> 3.5'
|
||||||
gem 'ostatus2', '~> 2.0'
|
gem 'ostatus2', '~> 2.0'
|
||||||
gem 'ox', '~> 2.10'
|
gem 'ox', '~> 2.9'
|
||||||
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
|
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
|
||||||
gem 'pundit', '~> 2.0'
|
gem 'pundit', '~> 1.1'
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'rack-attack', '~> 5.4'
|
gem 'rack-attack', '~> 5.2'
|
||||||
gem 'rack-cors', '~> 1.0', require: 'rack/cors'
|
gem 'rack-cors', '~> 1.0', require: 'rack/cors'
|
||||||
gem 'rails-i18n', '~> 5.1'
|
gem 'rails-i18n', '~> 5.1'
|
||||||
gem 'rails-settings-cached', '~> 0.6'
|
gem 'rails-settings-cached', '~> 0.6'
|
||||||
gem 'redis', '~> 4.0', require: ['redis', 'redis/connection/hiredis']
|
gem 'redis', '~> 4.0', 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 'sanitize', '~> 5.0'
|
gem 'ruby-progressbar', '~> 1.4'
|
||||||
gem 'sidekiq', '~> 5.2'
|
gem 'sanitize', '~> 4.6'
|
||||||
gem 'sidekiq-scheduler', '~> 3.0'
|
gem 'sidekiq', '~> 5.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', '~> 4.0'
|
||||||
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
gem 'sprockets-rails', '~> 3.2', require: 'sprockets/railtie'
|
||||||
gem 'stoplight', '~> 2.1.3'
|
gem 'stoplight', '~> 2.1.3'
|
||||||
gem 'strong_migrations', '~> 0.3'
|
gem 'strong_migrations', '~> 0.2'
|
||||||
gem 'tty-command', '~> 0.8', require: false
|
gem 'tty-command', '~> 0.8', require: false
|
||||||
gem 'tty-prompt', '~> 0.17', require: false
|
gem 'tty-prompt', '~> 0.16', require: false
|
||||||
gem 'twitter-text', '~> 1.14'
|
gem 'twitter-text', '~> 1.14'
|
||||||
gem 'tzinfo-data', '~> 1.2018'
|
gem 'tzinfo-data', '~> 1.2018'
|
||||||
gem 'webpacker', '~> 3.5'
|
gem 'webpacker', '~> 3.4'
|
||||||
gem 'webpush'
|
gem 'webpush'
|
||||||
|
|
||||||
gem 'json-ld', '~> 2.2'
|
gem 'json-ld', '~> 2.2'
|
||||||
|
@ -94,45 +94,45 @@ gem 'rdf-normalize', '~> 0.3'
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'fabrication', '~> 2.20'
|
gem 'fabrication', '~> 2.20'
|
||||||
gem 'fuubar', '~> 2.3'
|
gem 'fuubar', '~> 2.2'
|
||||||
gem 'i18n-tasks', '~> 0.9', require: false
|
gem 'i18n-tasks', '~> 0.9', require: false
|
||||||
gem 'pry-byebug', '~> 3.6'
|
gem 'pry-byebug', '~> 3.6'
|
||||||
gem 'pry-rails', '~> 0.3'
|
gem 'pry-rails', '~> 0.3'
|
||||||
gem 'rspec-rails', '~> 3.8'
|
gem 'rspec-rails', '~> 3.7'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :production, :test do
|
group :production, :test do
|
||||||
gem 'private_address_check', '~> 0.5'
|
gem 'private_address_check', '~> 0.4.1'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'capybara', '~> 3.10'
|
gem 'capybara', '~> 2.18'
|
||||||
gem 'climate_control', '~> 0.2'
|
gem 'climate_control', '~> 0.2'
|
||||||
gem 'faker', '~> 1.9'
|
gem 'faker', '~> 1.8'
|
||||||
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.16', require: false
|
gem 'simplecov', '~> 0.16', require: false
|
||||||
gem 'webmock', '~> 3.4'
|
gem 'webmock', '~> 3.3'
|
||||||
gem 'parallel_tests', '~> 2.26'
|
gem 'parallel_tests', '~> 2.21'
|
||||||
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.5'
|
gem 'better_errors', '~> 2.4'
|
||||||
gem 'binding_of_caller', '~> 0.7'
|
gem 'binding_of_caller', '~> 0.7'
|
||||||
gem 'bullet', '~> 5.7'
|
gem 'bullet', '~> 5.7'
|
||||||
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 'memory_profiler'
|
||||||
gem 'rubocop', '~> 0.60', require: false
|
gem 'rubocop', '~> 0.55', require: false
|
||||||
gem 'brakeman', '~> 4.3', require: false
|
gem 'brakeman', '~> 4.2', require: false
|
||||||
gem 'bundler-audit', '~> 0.6', require: false
|
gem 'bundler-audit', '~> 0.6', require: false
|
||||||
gem 'scss_lint', '~> 0.57', require: false
|
gem 'scss_lint', '~> 0.57', require: false
|
||||||
|
|
||||||
gem 'capistrano', '~> 3.11'
|
gem 'capistrano', '~> 3.10'
|
||||||
gem 'capistrano-rails', '~> 1.4'
|
gem 'capistrano-rails', '~> 1.3'
|
||||||
gem 'capistrano-rbenv', '~> 2.1'
|
gem 'capistrano-rbenv', '~> 2.1'
|
||||||
gem 'capistrano-yarn', '~> 2.0'
|
gem 'capistrano-yarn', '~> 2.0'
|
||||||
|
|
||||||
|
|
429
Gemfile.lock
|
@ -15,25 +15,25 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (5.2.1)
|
actioncable (5.2.0)
|
||||||
actionpack (= 5.2.1)
|
actionpack (= 5.2.0)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailer (5.2.1)
|
actionmailer (5.2.0)
|
||||||
actionpack (= 5.2.1)
|
actionpack (= 5.2.0)
|
||||||
actionview (= 5.2.1)
|
actionview (= 5.2.0)
|
||||||
activejob (= 5.2.1)
|
activejob (= 5.2.0)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (5.2.1)
|
actionpack (5.2.0)
|
||||||
actionview (= 5.2.1)
|
actionview (= 5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
rack (~> 2.0)
|
rack (~> 2.0)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (5.2.1)
|
actionview (5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
|
@ -44,20 +44,20 @@ GEM
|
||||||
case_transform (>= 0.2)
|
case_transform (>= 0.2)
|
||||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||||
active_record_query_trace (1.5.4)
|
active_record_query_trace (1.5.4)
|
||||||
activejob (5.2.1)
|
activejob (5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (5.2.1)
|
activemodel (5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
activerecord (5.2.1)
|
activerecord (5.2.0)
|
||||||
activemodel (= 5.2.1)
|
activemodel (= 5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
arel (>= 9.0)
|
arel (>= 9.0)
|
||||||
activestorage (5.2.1)
|
activestorage (5.2.0)
|
||||||
actionpack (= 5.2.1)
|
actionpack (= 5.2.0)
|
||||||
activerecord (= 5.2.1)
|
activerecord (= 5.2.0)
|
||||||
marcel (~> 0.3.1)
|
marcel (~> 0.3.1)
|
||||||
activesupport (5.2.1)
|
activesupport (5.2.0)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
|
@ -66,7 +66,7 @@ GEM
|
||||||
public_suffix (>= 2.0.2, < 4.0)
|
public_suffix (>= 2.0.2, < 4.0)
|
||||||
airbrussh (1.3.0)
|
airbrussh (1.3.0)
|
||||||
sshkit (>= 1.6.1, != 1.7.0)
|
sshkit (>= 1.6.1, != 1.7.0)
|
||||||
annotate (2.7.4)
|
annotate (2.7.3)
|
||||||
activerecord (>= 3.2, < 6.0)
|
activerecord (>= 3.2, < 6.0)
|
||||||
rake (>= 10.4, < 13.0)
|
rake (>= 10.4, < 13.0)
|
||||||
arel (9.0.0)
|
arel (9.0.0)
|
||||||
|
@ -75,42 +75,40 @@ GEM
|
||||||
encryptor (~> 3.0.0)
|
encryptor (~> 3.0.0)
|
||||||
av (0.9.0)
|
av (0.9.0)
|
||||||
cocaine (~> 0.5.3)
|
cocaine (~> 0.5.3)
|
||||||
aws-eventstream (1.0.1)
|
aws-partitions (1.80.0)
|
||||||
aws-partitions (1.106.0)
|
aws-sdk-core (3.19.0)
|
||||||
aws-sdk-core (3.35.0)
|
|
||||||
aws-eventstream (~> 1.0)
|
|
||||||
aws-partitions (~> 1.0)
|
aws-partitions (~> 1.0)
|
||||||
aws-sigv4 (~> 1.0)
|
aws-sigv4 (~> 1.0)
|
||||||
jmespath (~> 1.0)
|
jmespath (~> 1.0)
|
||||||
aws-sdk-kms (1.11.0)
|
aws-sdk-kms (1.5.0)
|
||||||
aws-sdk-core (~> 3, >= 3.26.0)
|
aws-sdk-core (~> 3)
|
||||||
aws-sigv4 (~> 1.0)
|
aws-sigv4 (~> 1.0)
|
||||||
aws-sdk-s3 (1.23.0)
|
aws-sdk-s3 (1.9.1)
|
||||||
aws-sdk-core (~> 3, >= 3.26.0)
|
aws-sdk-core (~> 3)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.0)
|
aws-sigv4 (~> 1.0)
|
||||||
aws-sigv4 (1.0.3)
|
aws-sigv4 (1.0.2)
|
||||||
bcrypt (3.1.12)
|
bcrypt (3.1.12)
|
||||||
benchmark-ips (2.7.2)
|
benchmark-ips (2.7.2)
|
||||||
better_errors (2.5.0)
|
better_errors (2.4.0)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubi (>= 1.0.0)
|
erubi (>= 1.0.0)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
binding_of_caller (0.8.0)
|
binding_of_caller (0.8.0)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
bootsnap (1.3.2)
|
bootsnap (1.3.0)
|
||||||
msgpack (~> 1.0)
|
msgpack (~> 1.0)
|
||||||
brakeman (4.3.1)
|
brakeman (4.2.1)
|
||||||
browser (2.5.3)
|
browser (2.5.3)
|
||||||
builder (3.2.3)
|
builder (3.2.3)
|
||||||
bullet (5.7.6)
|
bullet (5.7.5)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
uniform_notifier (~> 1.11.0)
|
uniform_notifier (~> 1.11.0)
|
||||||
bundler-audit (0.6.0)
|
bundler-audit (0.6.0)
|
||||||
bundler (~> 1.2)
|
bundler (~> 1.2)
|
||||||
thor (~> 0.18)
|
thor (~> 0.18)
|
||||||
byebug (10.0.2)
|
byebug (10.0.2)
|
||||||
capistrano (3.11.0)
|
capistrano (3.10.2)
|
||||||
airbrussh (>= 1.0.0)
|
airbrussh (>= 1.0.0)
|
||||||
i18n
|
i18n
|
||||||
rake (>= 10.0.0)
|
rake (>= 10.0.0)
|
||||||
|
@ -118,22 +116,21 @@ GEM
|
||||||
capistrano-bundler (1.3.0)
|
capistrano-bundler (1.3.0)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
sshkit (~> 1.2)
|
sshkit (~> 1.2)
|
||||||
capistrano-rails (1.4.0)
|
capistrano-rails (1.3.1)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
capistrano-bundler (~> 1.1)
|
capistrano-bundler (~> 1.1)
|
||||||
capistrano-rbenv (2.1.4)
|
capistrano-rbenv (2.1.3)
|
||||||
capistrano (~> 3.1)
|
capistrano (~> 3.1)
|
||||||
sshkit (~> 1.3)
|
sshkit (~> 1.3)
|
||||||
capistrano-yarn (2.0.2)
|
capistrano-yarn (2.0.2)
|
||||||
capistrano (~> 3.0)
|
capistrano (~> 3.0)
|
||||||
capybara (3.10.0)
|
capybara (2.18.0)
|
||||||
addressable
|
addressable
|
||||||
mini_mime (>= 0.1.3)
|
mini_mime (>= 0.1.3)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (>= 1.3.3)
|
||||||
rack (>= 1.6.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.5.4)
|
||||||
regexp_parser (~> 1.2)
|
xpath (>= 2.0, < 4.0)
|
||||||
xpath (~> 3.2)
|
|
||||||
case_transform (0.2)
|
case_transform (0.2)
|
||||||
activesupport
|
activesupport
|
||||||
charlock_holmes (0.7.6)
|
charlock_holmes (0.7.6)
|
||||||
|
@ -148,15 +145,16 @@ GEM
|
||||||
cocaine (0.5.8)
|
cocaine (0.5.8)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
|
colorize (0.8.1)
|
||||||
concurrent-ruby (1.0.5)
|
concurrent-ruby (1.0.5)
|
||||||
connection_pool (2.2.2)
|
connection_pool (2.2.1)
|
||||||
crack (0.4.3)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
crass (1.0.4)
|
crass (1.0.4)
|
||||||
css_parser (1.6.0)
|
css_parser (1.6.0)
|
||||||
addressable
|
addressable
|
||||||
debug_inspector (0.0.3)
|
debug_inspector (0.0.3)
|
||||||
derailed_benchmarks (1.3.5)
|
derailed_benchmarks (1.3.4)
|
||||||
benchmark-ips (~> 2)
|
benchmark-ips (~> 2)
|
||||||
get_process_mem (~> 0)
|
get_process_mem (~> 0)
|
||||||
heapy (~> 0)
|
heapy (~> 0)
|
||||||
|
@ -164,7 +162,7 @@ GEM
|
||||||
rack (>= 1)
|
rack (>= 1)
|
||||||
rake (> 10, < 13)
|
rake (> 10, < 13)
|
||||||
thor (~> 0.19)
|
thor (~> 0.19)
|
||||||
devise (4.5.0)
|
devise (4.4.3)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0, < 6.0)
|
railties (>= 4.1.0, < 6.0)
|
||||||
|
@ -176,19 +174,22 @@ GEM
|
||||||
devise (~> 4.0)
|
devise (~> 4.0)
|
||||||
railties (< 5.3)
|
railties (< 5.3)
|
||||||
rotp (~> 2.0)
|
rotp (~> 2.0)
|
||||||
devise_pam_authenticatable2 (9.2.0)
|
devise_pam_authenticatable2 (9.1.0)
|
||||||
devise (>= 4.0.0)
|
devise (>= 4.0.0)
|
||||||
rpam2 (~> 4.0)
|
rpam2 (~> 4.0)
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
docile (1.3.0)
|
docile (1.3.0)
|
||||||
domain_name (0.5.20180417)
|
domain_name (0.5.20180417)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
doorkeeper (5.0.2)
|
doorkeeper (4.4.2)
|
||||||
railties (>= 4.2)
|
railties (>= 4.2)
|
||||||
dotenv (2.5.0)
|
dotenv (2.2.2)
|
||||||
dotenv-rails (2.5.0)
|
dotenv-rails (2.2.2)
|
||||||
dotenv (= 2.5.0)
|
dotenv (= 2.2.2)
|
||||||
railties (>= 3.2, < 6.0)
|
railties (>= 3.2, < 6.0)
|
||||||
|
easy_translate (0.5.1)
|
||||||
|
thread
|
||||||
|
thread_safe
|
||||||
elasticsearch (6.0.2)
|
elasticsearch (6.0.2)
|
||||||
elasticsearch-api (= 6.0.2)
|
elasticsearch-api (= 6.0.2)
|
||||||
elasticsearch-transport (= 6.0.2)
|
elasticsearch-transport (= 6.0.2)
|
||||||
|
@ -201,37 +202,35 @@ GEM
|
||||||
encryptor (3.0.0)
|
encryptor (3.0.0)
|
||||||
equatable (0.5.0)
|
equatable (0.5.0)
|
||||||
erubi (1.7.1)
|
erubi (1.7.1)
|
||||||
et-orbi (1.1.6)
|
et-orbi (1.1.0)
|
||||||
tzinfo
|
tzinfo
|
||||||
excon (0.62.0)
|
excon (0.62.0)
|
||||||
fabrication (2.20.1)
|
fabrication (2.20.1)
|
||||||
faker (1.9.1)
|
faker (1.8.7)
|
||||||
i18n (>= 0.7)
|
i18n (>= 0.7)
|
||||||
faraday (0.15.0)
|
faraday (0.15.0)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
fast_blank (1.0.0)
|
fast_blank (1.0.0)
|
||||||
fastimage (2.1.4)
|
fastimage (2.1.1)
|
||||||
ffi (1.9.25)
|
ffi (1.9.23)
|
||||||
fog-core (2.1.0)
|
fog-core (1.45.0)
|
||||||
builder
|
builder
|
||||||
excon (~> 0.58)
|
excon (~> 0.58)
|
||||||
formatador (~> 0.2)
|
formatador (~> 0.2)
|
||||||
mime-types
|
fog-json (1.0.2)
|
||||||
fog-json (1.2.0)
|
fog-core (~> 1.0)
|
||||||
fog-core
|
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
fog-openstack (0.3.7)
|
fog-local (0.5.0)
|
||||||
fog-core (>= 1.45, <= 2.1.0)
|
fog-core (>= 1.27, < 3.0)
|
||||||
|
fog-openstack (0.1.25)
|
||||||
|
fog-core (~> 1.40)
|
||||||
fog-json (>= 1.0)
|
fog-json (>= 1.0)
|
||||||
ipaddress (>= 0.8)
|
ipaddress (>= 0.8)
|
||||||
formatador (0.2.5)
|
formatador (0.2.5)
|
||||||
fugit (1.1.6)
|
fuubar (2.3.1)
|
||||||
et-orbi (~> 1.1, >= 1.1.6)
|
|
||||||
raabro (~> 1.1)
|
|
||||||
fuubar (2.3.2)
|
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
get_process_mem (0.2.2)
|
get_process_mem (0.2.1)
|
||||||
globalid (0.4.1)
|
globalid (0.4.1)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
goldfinger (2.1.0)
|
goldfinger (2.1.0)
|
||||||
|
@ -252,40 +251,39 @@ GEM
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
hashdiff (0.3.7)
|
hashdiff (0.3.7)
|
||||||
hashie (3.5.7)
|
hashie (3.5.7)
|
||||||
heapy (0.1.4)
|
heapy (0.1.3)
|
||||||
highline (2.0.0)
|
highline (1.7.10)
|
||||||
hiredis (0.6.1)
|
hiredis (0.6.1)
|
||||||
hitimes (1.3.0)
|
hitimes (1.2.6)
|
||||||
hkdf (0.3.0)
|
hkdf (0.3.0)
|
||||||
htmlentities (4.3.4)
|
htmlentities (4.3.4)
|
||||||
http (3.3.0)
|
http (3.2.0)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
http-cookie (~> 1.0)
|
http-cookie (~> 1.0)
|
||||||
http-form_data (~> 2.0)
|
http-form_data (~> 2.0)
|
||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0.6.0)
|
||||||
http-cookie (1.0.3)
|
http-cookie (1.0.3)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http-form_data (2.1.1)
|
http-form_data (2.1.0)
|
||||||
http_accept_language (2.1.1)
|
http_accept_language (2.1.1)
|
||||||
httplog (1.1.1)
|
httplog (1.0.2)
|
||||||
|
colorize (~> 0.8)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rainbow (>= 2.0.0)
|
i18n (1.1.0)
|
||||||
i18n (1.1.1)
|
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
i18n-tasks (0.9.28)
|
i18n-tasks (0.9.21)
|
||||||
activesupport (>= 4.0.2)
|
activesupport (>= 4.0.2)
|
||||||
ast (>= 2.1.0)
|
ast (>= 2.1.0)
|
||||||
|
easy_translate (>= 0.5.1)
|
||||||
erubi
|
erubi
|
||||||
highline (>= 2.0.0)
|
highline (>= 1.7.3)
|
||||||
i18n
|
i18n
|
||||||
parser (>= 2.2.3.0)
|
parser (>= 2.2.3.0)
|
||||||
rails-i18n
|
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
terminal-table (>= 1.5.1)
|
terminal-table (>= 1.5.1)
|
||||||
idn-ruby (0.1.0)
|
idn-ruby (0.1.0)
|
||||||
ipaddress (0.8.3)
|
ipaddress (0.8.3)
|
||||||
iso-639 (0.2.8)
|
iso-639 (0.2.8)
|
||||||
jaro_winkler (1.5.1)
|
|
||||||
jmespath (1.4.0)
|
jmespath (1.4.0)
|
||||||
json (2.1.0)
|
json (2.1.0)
|
||||||
json-ld (2.2.1)
|
json-ld (2.2.1)
|
||||||
|
@ -319,27 +317,25 @@ GEM
|
||||||
activesupport (>= 4)
|
activesupport (>= 4)
|
||||||
railties (>= 4)
|
railties (>= 4)
|
||||||
request_store (~> 1.0)
|
request_store (~> 1.0)
|
||||||
loofah (2.2.3)
|
loofah (2.2.2)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.7.0)
|
mail (2.7.0)
|
||||||
mini_mime (>= 0.1.1)
|
mini_mime (>= 0.1.1)
|
||||||
makara (0.4.0)
|
|
||||||
activerecord (>= 3.0.0)
|
|
||||||
marcel (0.3.2)
|
marcel (0.3.2)
|
||||||
mimemagic (~> 0.3.2)
|
mimemagic (~> 0.3.2)
|
||||||
mario-redis-lock (1.2.1)
|
mario-redis-lock (1.2.1)
|
||||||
redis (>= 3.0.5)
|
redis (>= 3.0.5)
|
||||||
memory_profiler (0.9.12)
|
memory_profiler (0.9.10)
|
||||||
method_source (0.9.0)
|
method_source (0.9.0)
|
||||||
microformats (4.0.7)
|
microformats (4.0.7)
|
||||||
json
|
json
|
||||||
nokogiri
|
nokogiri
|
||||||
mime-types (3.2.2)
|
mime-types (3.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2018.0812)
|
mime-types-data (3.2016.0521)
|
||||||
mimemagic (0.3.2)
|
mimemagic (0.3.2)
|
||||||
mini_mime (1.0.1)
|
mini_mime (1.0.0)
|
||||||
mini_portile2 (2.3.0)
|
mini_portile2 (2.3.0)
|
||||||
minitest (5.11.3)
|
minitest (5.11.3)
|
||||||
msgpack (1.2.4)
|
msgpack (1.2.4)
|
||||||
|
@ -349,18 +345,18 @@ GEM
|
||||||
net-ldap (0.16.1)
|
net-ldap (0.16.1)
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (5.0.2)
|
net-ssh (4.2.0)
|
||||||
nio4r (2.3.1)
|
nio4r (2.3.0)
|
||||||
nokogiri (1.8.5)
|
nokogiri (1.8.4)
|
||||||
mini_portile2 (~> 2.3.0)
|
mini_portile2 (~> 2.3.0)
|
||||||
nokogumbo (2.0.0)
|
nokogumbo (1.5.0)
|
||||||
nokogiri (~> 1.8, >= 1.8.4)
|
nokogiri
|
||||||
nsa (0.2.4)
|
nsa (0.2.4)
|
||||||
activesupport (>= 4.2, < 6)
|
activesupport (>= 4.2, < 6)
|
||||||
concurrent-ruby (~> 1.0.0)
|
concurrent-ruby (~> 1.0.0)
|
||||||
sidekiq (>= 3.5.0)
|
sidekiq (>= 3.5.0)
|
||||||
statsd-ruby (~> 1.2.0)
|
statsd-ruby (~> 1.2.0)
|
||||||
oj (3.7.0)
|
oj (3.5.1)
|
||||||
omniauth (1.8.1)
|
omniauth (1.8.1)
|
||||||
hashie (>= 3.4.6, < 3.6.0)
|
hashie (>= 3.4.6, < 3.6.0)
|
||||||
rack (>= 1.6.2, < 3)
|
rack (>= 1.6.2, < 3)
|
||||||
|
@ -368,7 +364,7 @@ GEM
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
nokogiri (~> 1.5)
|
nokogiri (~> 1.5)
|
||||||
omniauth (~> 1.2)
|
omniauth (~> 1.2)
|
||||||
omniauth-saml (1.10.1)
|
omniauth-saml (1.10.0)
|
||||||
omniauth (~> 1.3, >= 1.3.2)
|
omniauth (~> 1.3, >= 1.3.2)
|
||||||
ruby-saml (~> 1.7)
|
ruby-saml (~> 1.7)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
|
@ -376,7 +372,7 @@ GEM
|
||||||
addressable (~> 2.5)
|
addressable (~> 2.5)
|
||||||
http (~> 3.0)
|
http (~> 3.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
ox (2.10.0)
|
ox (2.9.2)
|
||||||
paperclip (6.0.0)
|
paperclip (6.0.0)
|
||||||
activemodel (>= 4.2.0)
|
activemodel (>= 4.2.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
|
@ -387,18 +383,18 @@ GEM
|
||||||
av (~> 0.9.0)
|
av (~> 0.9.0)
|
||||||
paperclip (>= 2.5.2)
|
paperclip (>= 2.5.2)
|
||||||
parallel (1.12.1)
|
parallel (1.12.1)
|
||||||
parallel_tests (2.26.0)
|
parallel_tests (2.21.3)
|
||||||
parallel
|
parallel
|
||||||
parser (2.5.3.0)
|
parser (2.5.1.0)
|
||||||
ast (~> 2.4.0)
|
ast (~> 2.4.0)
|
||||||
pastel (0.7.2)
|
pastel (0.7.2)
|
||||||
equatable (~> 0.5.0)
|
equatable (~> 0.5.0)
|
||||||
tty-color (~> 0.4.0)
|
tty-color (~> 0.4.0)
|
||||||
pg (1.1.3)
|
pg (1.0.0)
|
||||||
pghero (2.2.0)
|
pghero (2.1.0)
|
||||||
activerecord
|
activerecord
|
||||||
pkg-config (1.3.1)
|
pkg-config (1.3.0)
|
||||||
powerpack (0.1.2)
|
powerpack (0.1.1)
|
||||||
premailer (1.11.1)
|
premailer (1.11.1)
|
||||||
addressable
|
addressable
|
||||||
css_parser (>= 1.6.0)
|
css_parser (>= 1.6.0)
|
||||||
|
@ -406,7 +402,7 @@ GEM
|
||||||
premailer-rails (1.10.2)
|
premailer-rails (1.10.2)
|
||||||
actionmailer (>= 3, < 6)
|
actionmailer (>= 3, < 6)
|
||||||
premailer (~> 1.7, >= 1.7.9)
|
premailer (~> 1.7, >= 1.7.9)
|
||||||
private_address_check (0.5.0)
|
private_address_check (0.4.1)
|
||||||
pry (0.11.3)
|
pry (0.11.3)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.9.0)
|
method_source (~> 0.9.0)
|
||||||
|
@ -415,33 +411,32 @@ GEM
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
pry-rails (0.3.6)
|
pry-rails (0.3.6)
|
||||||
pry (>= 0.10.4)
|
pry (>= 0.10.4)
|
||||||
public_suffix (3.0.3)
|
public_suffix (3.0.2)
|
||||||
puma (3.12.0)
|
puma (3.11.4)
|
||||||
pundit (2.0.0)
|
pundit (1.1.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
raabro (1.1.6)
|
|
||||||
rack (2.0.5)
|
rack (2.0.5)
|
||||||
rack-attack (5.4.1)
|
rack-attack (5.2.0)
|
||||||
rack (>= 1.0, < 3)
|
rack
|
||||||
rack-cors (1.0.2)
|
rack-cors (1.0.2)
|
||||||
rack-protection (2.0.4)
|
rack-protection (2.0.1)
|
||||||
rack
|
rack
|
||||||
rack-proxy (0.6.4)
|
rack-proxy (0.6.4)
|
||||||
rack
|
rack
|
||||||
rack-test (1.1.0)
|
rack-test (1.1.0)
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rails (5.2.1)
|
rails (5.2.0)
|
||||||
actioncable (= 5.2.1)
|
actioncable (= 5.2.0)
|
||||||
actionmailer (= 5.2.1)
|
actionmailer (= 5.2.0)
|
||||||
actionpack (= 5.2.1)
|
actionpack (= 5.2.0)
|
||||||
actionview (= 5.2.1)
|
actionview (= 5.2.0)
|
||||||
activejob (= 5.2.1)
|
activejob (= 5.2.0)
|
||||||
activemodel (= 5.2.1)
|
activemodel (= 5.2.0)
|
||||||
activerecord (= 5.2.1)
|
activerecord (= 5.2.0)
|
||||||
activestorage (= 5.2.1)
|
activestorage (= 5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
bundler (>= 1.3.0)
|
bundler (>= 1.3.0)
|
||||||
railties (= 5.2.1)
|
railties (= 5.2.0)
|
||||||
sprockets-rails (>= 2.0.0)
|
sprockets-rails (>= 2.0.0)
|
||||||
rails-controller-testing (1.0.2)
|
rails-controller-testing (1.0.2)
|
||||||
actionpack (~> 5.x, >= 5.0.1)
|
actionpack (~> 5.x, >= 5.0.1)
|
||||||
|
@ -452,17 +447,17 @@ GEM
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.0.4)
|
rails-html-sanitizer (1.0.4)
|
||||||
loofah (~> 2.2, >= 2.2.2)
|
loofah (~> 2.2, >= 2.2.2)
|
||||||
rails-i18n (5.1.2)
|
rails-i18n (5.1.1)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 5.0, < 6)
|
railties (>= 5.0, < 6)
|
||||||
rails-settings-cached (0.6.6)
|
rails-settings-cached (0.6.6)
|
||||||
rails (>= 4.2.0)
|
rails (>= 4.2.0)
|
||||||
railties (5.2.1)
|
railties (5.2.0)
|
||||||
actionpack (= 5.2.1)
|
actionpack (= 5.2.0)
|
||||||
activesupport (= 5.2.1)
|
activesupport (= 5.2.0)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.19.0, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (3.0.0)
|
rainbow (3.0.0)
|
||||||
rake (12.3.1)
|
rake (12.3.1)
|
||||||
rb-fsevent (0.10.3)
|
rb-fsevent (0.10.3)
|
||||||
|
@ -473,7 +468,7 @@ GEM
|
||||||
link_header (~> 0.0, >= 0.0.8)
|
link_header (~> 0.0, >= 0.0.8)
|
||||||
rdf-normalize (0.3.3)
|
rdf-normalize (0.3.3)
|
||||||
rdf (>= 2.2, < 4.0)
|
rdf (>= 2.2, < 4.0)
|
||||||
redis (4.0.2)
|
redis (4.0.1)
|
||||||
redis-actionpack (5.0.2)
|
redis-actionpack (5.0.2)
|
||||||
actionpack (>= 4.0, < 6)
|
actionpack (>= 4.0, < 6)
|
||||||
redis-rack (>= 1, < 3)
|
redis-rack (>= 1, < 3)
|
||||||
|
@ -492,7 +487,6 @@ GEM
|
||||||
redis-store (>= 1.2, < 2)
|
redis-store (>= 1.2, < 2)
|
||||||
redis-store (1.5.0)
|
redis-store (1.5.0)
|
||||||
redis (>= 2.2, < 5)
|
redis (>= 2.2, < 5)
|
||||||
regexp_parser (1.2.0)
|
|
||||||
request_store (1.4.1)
|
request_store (1.4.1)
|
||||||
rack (>= 1.4)
|
rack (>= 1.4)
|
||||||
responders (2.4.0)
|
responders (2.4.0)
|
||||||
|
@ -502,60 +496,60 @@ GEM
|
||||||
rpam2 (4.0.2)
|
rpam2 (4.0.2)
|
||||||
rqrcode (0.10.1)
|
rqrcode (0.10.1)
|
||||||
chunky_png (~> 1.0)
|
chunky_png (~> 1.0)
|
||||||
rspec-core (3.8.0)
|
rspec-core (3.7.1)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.7.0)
|
||||||
rspec-expectations (3.8.2)
|
rspec-expectations (3.7.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.7.0)
|
||||||
rspec-mocks (3.8.0)
|
rspec-mocks (3.7.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.7.0)
|
||||||
rspec-rails (3.8.1)
|
rspec-rails (3.7.2)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
rspec-core (~> 3.8.0)
|
rspec-core (~> 3.7.0)
|
||||||
rspec-expectations (~> 3.8.0)
|
rspec-expectations (~> 3.7.0)
|
||||||
rspec-mocks (~> 3.8.0)
|
rspec-mocks (~> 3.7.0)
|
||||||
rspec-support (~> 3.8.0)
|
rspec-support (~> 3.7.0)
|
||||||
rspec-sidekiq (3.0.3)
|
rspec-sidekiq (3.0.3)
|
||||||
rspec-core (~> 3.0, >= 3.0.0)
|
rspec-core (~> 3.0, >= 3.0.0)
|
||||||
sidekiq (>= 2.4.0)
|
sidekiq (>= 2.4.0)
|
||||||
rspec-support (3.8.0)
|
rspec-support (3.7.1)
|
||||||
rubocop (0.60.0)
|
rubocop (0.55.0)
|
||||||
jaro_winkler (~> 1.5.1)
|
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 2.5, != 2.5.1.1)
|
parser (>= 2.5)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 2.2.2, < 4.0)
|
rainbow (>= 2.2.2, < 4.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (~> 1.4.0)
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||||
ruby-progressbar (1.10.0)
|
ruby-progressbar (1.9.0)
|
||||||
ruby-saml (1.9.0)
|
ruby-saml (1.7.2)
|
||||||
nokogiri (>= 1.5.10)
|
nokogiri (>= 1.5.10)
|
||||||
rufus-scheduler (3.5.2)
|
rufus-scheduler (3.4.2)
|
||||||
fugit (~> 1.1, >= 1.1.5)
|
et-orbi (~> 1.0)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
sanitize (5.0.0)
|
sanitize (4.6.4)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.8.0)
|
nokogiri (>= 1.4.4)
|
||||||
nokogumbo (~> 2.0)
|
nokogumbo (~> 1.4)
|
||||||
sass (3.6.0)
|
sass (3.5.6)
|
||||||
sass-listen (~> 4.0.0)
|
sass-listen (~> 4.0.0)
|
||||||
sass-listen (4.0.0)
|
sass-listen (4.0.0)
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
scss_lint (0.57.1)
|
scss_lint (0.57.0)
|
||||||
rake (>= 0.9, < 13)
|
rake (>= 0.9, < 13)
|
||||||
sass (~> 3.5, >= 3.5.5)
|
sass (~> 3.5.5)
|
||||||
sidekiq (5.2.2)
|
sidekiq (5.1.3)
|
||||||
connection_pool (~> 2.2, >= 2.2.2)
|
concurrent-ruby (~> 1.0)
|
||||||
|
connection_pool (~> 2.2, >= 2.2.0)
|
||||||
rack-protection (>= 1.5.0)
|
rack-protection (>= 1.5.0)
|
||||||
redis (>= 3.3.5, < 5)
|
redis (>= 3.3.5, < 5)
|
||||||
sidekiq-bulk (0.1.1)
|
sidekiq-bulk (0.1.1)
|
||||||
activesupport
|
activesupport
|
||||||
sidekiq
|
sidekiq
|
||||||
sidekiq-scheduler (3.0.0)
|
sidekiq-scheduler (2.2.1)
|
||||||
redis (>= 3, < 5)
|
redis (>= 3, < 5)
|
||||||
rufus-scheduler (~> 3.2)
|
rufus-scheduler (~> 3.2)
|
||||||
sidekiq (>= 3)
|
sidekiq (>= 3)
|
||||||
|
@ -565,9 +559,9 @@ GEM
|
||||||
thor (~> 0)
|
thor (~> 0)
|
||||||
simple-navigation (4.0.5)
|
simple-navigation (4.0.5)
|
||||||
activesupport (>= 2.3.2)
|
activesupport (>= 2.3.2)
|
||||||
simple_form (4.0.1)
|
simple_form (4.0.0)
|
||||||
actionpack (>= 5.0)
|
actionpack (> 4)
|
||||||
activemodel (>= 5.0)
|
activemodel (> 4)
|
||||||
simplecov (0.16.1)
|
simplecov (0.16.1)
|
||||||
docile (~> 1.1)
|
docile (~> 1.1)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
|
@ -580,15 +574,15 @@ GEM
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
sshkit (1.17.0)
|
sshkit (1.16.0)
|
||||||
net-scp (>= 1.1.2)
|
net-scp (>= 1.1.2)
|
||||||
net-ssh (>= 2.8.0)
|
net-ssh (>= 2.8.0)
|
||||||
stackprof (0.2.12)
|
stackprof (0.2.11)
|
||||||
statsd-ruby (1.2.1)
|
statsd-ruby (1.2.1)
|
||||||
stoplight (2.1.3)
|
stoplight (2.1.3)
|
||||||
streamio-ffmpeg (3.0.2)
|
streamio-ffmpeg (3.0.2)
|
||||||
multi_json (~> 1.8)
|
multi_json (~> 1.8)
|
||||||
strong_migrations (0.3.1)
|
strong_migrations (0.2.2)
|
||||||
activerecord (>= 3.2.0)
|
activerecord (>= 3.2.0)
|
||||||
temple (0.8.0)
|
temple (0.8.0)
|
||||||
terminal-table (1.8.0)
|
terminal-table (1.8.0)
|
||||||
|
@ -596,54 +590,55 @@ GEM
|
||||||
terrapin (0.6.0)
|
terrapin (0.6.0)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
thor (0.20.0)
|
thor (0.20.0)
|
||||||
|
thread (0.2.2)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.8)
|
tilt (2.0.8)
|
||||||
timers (4.1.2)
|
timers (4.1.2)
|
||||||
hitimes
|
hitimes
|
||||||
tty-color (0.4.3)
|
tty-color (0.4.2)
|
||||||
tty-command (0.8.2)
|
tty-command (0.8.0)
|
||||||
pastel (~> 0.7.0)
|
pastel (~> 0.7.0)
|
||||||
tty-cursor (0.6.0)
|
tty-cursor (0.5.0)
|
||||||
tty-prompt (0.17.1)
|
tty-prompt (0.16.0)
|
||||||
necromancer (~> 0.4.0)
|
necromancer (~> 0.4.0)
|
||||||
pastel (~> 0.7.0)
|
pastel (~> 0.7.0)
|
||||||
timers (~> 4.0)
|
timers (~> 4.0)
|
||||||
tty-cursor (~> 0.6.0)
|
tty-cursor (~> 0.5.0)
|
||||||
tty-reader (~> 0.4.0)
|
tty-reader (~> 0.2.0)
|
||||||
tty-reader (0.4.0)
|
tty-reader (0.2.0)
|
||||||
tty-cursor (~> 0.6.0)
|
tty-cursor (~> 0.5.0)
|
||||||
tty-screen (~> 0.6.4)
|
tty-screen (~> 0.6.4)
|
||||||
wisper (~> 2.0.0)
|
wisper (~> 2.0.0)
|
||||||
tty-screen (0.6.5)
|
tty-screen (0.6.4)
|
||||||
twitter-text (1.14.7)
|
twitter-text (1.14.7)
|
||||||
unf (~> 0.1.0)
|
unf (~> 0.1.0)
|
||||||
tzinfo (1.2.5)
|
tzinfo (1.2.5)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
tzinfo-data (1.2018.7)
|
tzinfo-data (1.2018.4)
|
||||||
tzinfo (>= 1.0.0)
|
tzinfo (>= 1.0.0)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.5)
|
unf_ext (0.0.7.5)
|
||||||
unicode-display_width (1.4.0)
|
unicode-display_width (1.3.2)
|
||||||
uniform_notifier (1.11.0)
|
uniform_notifier (1.11.0)
|
||||||
warden (1.2.7)
|
warden (1.2.7)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
webmock (3.4.2)
|
webmock (3.3.0)
|
||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
hashdiff
|
hashdiff
|
||||||
webpacker (3.5.5)
|
webpacker (3.4.3)
|
||||||
activesupport (>= 4.2)
|
activesupport (>= 4.2)
|
||||||
rack-proxy (>= 0.6.1)
|
rack-proxy (>= 0.6.1)
|
||||||
railties (>= 4.2)
|
railties (>= 4.2)
|
||||||
webpush (0.3.4)
|
webpush (0.3.3)
|
||||||
hkdf (~> 0.2)
|
hkdf (~> 0.2)
|
||||||
jwt (~> 2.0)
|
jwt (~> 2.0)
|
||||||
websocket-driver (0.7.0)
|
websocket-driver (0.7.0)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.3)
|
websocket-extensions (0.1.3)
|
||||||
wisper (2.0.0)
|
wisper (2.0.0)
|
||||||
xpath (3.2.0)
|
xpath (3.0.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
|
@ -654,44 +649,45 @@ DEPENDENCIES
|
||||||
active_record_query_trace (~> 1.5)
|
active_record_query_trace (~> 1.5)
|
||||||
addressable (~> 2.5)
|
addressable (~> 2.5)
|
||||||
annotate (~> 2.7)
|
annotate (~> 2.7)
|
||||||
aws-sdk-s3 (~> 1.23)
|
aws-sdk-s3 (~> 1.9)
|
||||||
better_errors (~> 2.5)
|
better_errors (~> 2.4)
|
||||||
binding_of_caller (~> 0.7)
|
binding_of_caller (~> 0.7)
|
||||||
bootsnap (~> 1.3)
|
bootsnap (~> 1.3)
|
||||||
brakeman (~> 4.3)
|
brakeman (~> 4.2)
|
||||||
browser
|
browser
|
||||||
bullet (~> 5.7)
|
bullet (~> 5.7)
|
||||||
bundler-audit (~> 0.6)
|
bundler-audit (~> 0.6)
|
||||||
capistrano (~> 3.11)
|
capistrano (~> 3.10)
|
||||||
capistrano-rails (~> 1.4)
|
capistrano-rails (~> 1.3)
|
||||||
capistrano-rbenv (~> 2.1)
|
capistrano-rbenv (~> 2.1)
|
||||||
capistrano-yarn (~> 2.0)
|
capistrano-yarn (~> 2.0)
|
||||||
capybara (~> 3.10)
|
capybara (~> 2.18)
|
||||||
charlock_holmes (~> 0.7.6)
|
charlock_holmes (~> 0.7.6)
|
||||||
chewy (~> 5.0)
|
chewy (~> 5.0)
|
||||||
cld3 (~> 3.2.0)
|
cld3 (~> 3.2.0)
|
||||||
climate_control (~> 0.2)
|
climate_control (~> 0.2)
|
||||||
derailed_benchmarks
|
derailed_benchmarks
|
||||||
devise (~> 4.5)
|
devise (~> 4.4)
|
||||||
devise-two-factor (~> 3.0)
|
devise-two-factor (~> 3.0)
|
||||||
devise_pam_authenticatable2 (~> 9.2)
|
devise_pam_authenticatable2 (~> 9.1)
|
||||||
doorkeeper (~> 5.0)
|
doorkeeper (~> 4.4)
|
||||||
dotenv-rails (~> 2.5)
|
dotenv-rails (~> 2.2, < 2.3)
|
||||||
fabrication (~> 2.20)
|
fabrication (~> 2.20)
|
||||||
faker (~> 1.9)
|
faker (~> 1.8)
|
||||||
fast_blank (~> 1.0)
|
fast_blank (~> 1.0)
|
||||||
fastimage
|
fastimage
|
||||||
fog-core (<= 2.1.0)
|
fog-core (~> 1.45)
|
||||||
fog-openstack (~> 0.3)
|
fog-local (~> 0.5)
|
||||||
fuubar (~> 2.3)
|
fog-openstack (~> 0.1)
|
||||||
|
fuubar (~> 2.2)
|
||||||
goldfinger (~> 2.1)
|
goldfinger (~> 2.1)
|
||||||
hamlit-rails (~> 0.2)
|
hamlit-rails (~> 0.2)
|
||||||
hiredis (~> 0.6)
|
hiredis (~> 0.6)
|
||||||
htmlentities (~> 4.3)
|
htmlentities (~> 4.3)
|
||||||
http (~> 3.3)
|
http (~> 3.2)
|
||||||
http_accept_language (~> 2.1)
|
http_accept_language (~> 2.1)
|
||||||
http_parser.rb (~> 0.6)!
|
http_parser.rb (~> 0.6)!
|
||||||
httplog (~> 1.1)
|
httplog (~> 1.0)
|
||||||
i18n-tasks (~> 0.9)
|
i18n-tasks (~> 0.9)
|
||||||
idn-ruby
|
idn-ruby
|
||||||
iso-639
|
iso-639
|
||||||
|
@ -701,36 +697,35 @@ DEPENDENCIES
|
||||||
letter_opener_web (~> 1.3)
|
letter_opener_web (~> 1.3)
|
||||||
link_header (~> 0.0)
|
link_header (~> 0.0)
|
||||||
lograge (~> 0.10)
|
lograge (~> 0.10)
|
||||||
makara (~> 0.4)
|
|
||||||
mario-redis-lock (~> 1.2)
|
mario-redis-lock (~> 1.2)
|
||||||
memory_profiler
|
memory_profiler
|
||||||
microformats (~> 4.0)
|
microformats (~> 4.0)
|
||||||
mime-types (~> 3.2)
|
mime-types (~> 3.1)
|
||||||
net-ldap (~> 0.10)
|
net-ldap (~> 0.10)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
nsa (~> 0.2)
|
nsa (~> 0.2)
|
||||||
oj (~> 3.7)
|
oj (~> 3.5)
|
||||||
omniauth (~> 1.2)
|
omniauth (~> 1.2)
|
||||||
omniauth-cas (~> 1.1)
|
omniauth-cas (~> 1.1)
|
||||||
omniauth-saml (~> 1.10)
|
omniauth-saml (~> 1.10)
|
||||||
ostatus2 (~> 2.0)
|
ostatus2 (~> 2.0)
|
||||||
ox (~> 2.10)
|
ox (~> 2.9)
|
||||||
paperclip (~> 6.0)
|
paperclip (~> 6.0)
|
||||||
paperclip-av-transcoder (~> 0.6)
|
paperclip-av-transcoder (~> 0.6)
|
||||||
parallel_tests (~> 2.26)
|
parallel_tests (~> 2.21)
|
||||||
pg (~> 1.1)
|
pg (~> 1.0)
|
||||||
pghero (~> 2.2)
|
pghero (~> 2.1)
|
||||||
pkg-config (~> 1.3)
|
pkg-config (~> 1.3)
|
||||||
posix-spawn!
|
posix-spawn!
|
||||||
premailer-rails
|
premailer-rails
|
||||||
private_address_check (~> 0.5)
|
private_address_check (~> 0.4.1)
|
||||||
pry-byebug (~> 3.6)
|
pry-byebug (~> 3.6)
|
||||||
pry-rails (~> 0.3)
|
pry-rails (~> 0.3)
|
||||||
puma (~> 3.12)
|
puma (~> 3.11)
|
||||||
pundit (~> 2.0)
|
pundit (~> 1.1)
|
||||||
rack-attack (~> 5.4)
|
rack-attack (~> 5.2)
|
||||||
rack-cors (~> 1.0)
|
rack-cors (~> 1.0)
|
||||||
rails (~> 5.2.1)
|
rails (~> 5.2.0)
|
||||||
rails-controller-testing (~> 1.0)
|
rails-controller-testing (~> 1.0)
|
||||||
rails-i18n (~> 5.1)
|
rails-i18n (~> 5.1)
|
||||||
rails-settings-cached (~> 0.6)
|
rails-settings-cached (~> 0.6)
|
||||||
|
@ -739,14 +734,15 @@ DEPENDENCIES
|
||||||
redis-namespace (~> 1.5)
|
redis-namespace (~> 1.5)
|
||||||
redis-rails (~> 5.0)
|
redis-rails (~> 5.0)
|
||||||
rqrcode (~> 0.10)
|
rqrcode (~> 0.10)
|
||||||
rspec-rails (~> 3.8)
|
rspec-rails (~> 3.7)
|
||||||
rspec-sidekiq (~> 3.0)
|
rspec-sidekiq (~> 3.0)
|
||||||
rubocop (~> 0.60)
|
rubocop (~> 0.55)
|
||||||
sanitize (~> 5.0)
|
ruby-progressbar (~> 1.4)
|
||||||
|
sanitize (~> 4.6)
|
||||||
scss_lint (~> 0.57)
|
scss_lint (~> 0.57)
|
||||||
sidekiq (~> 5.2)
|
sidekiq (~> 5.1)
|
||||||
sidekiq-bulk (~> 0.1.1)
|
sidekiq-bulk (~> 0.1.1)
|
||||||
sidekiq-scheduler (~> 3.0)
|
sidekiq-scheduler (~> 2.2)
|
||||||
sidekiq-unique-jobs (~> 5.0)
|
sidekiq-unique-jobs (~> 5.0)
|
||||||
simple-navigation (~> 4.0)
|
simple-navigation (~> 4.0)
|
||||||
simple_form (~> 4.0)
|
simple_form (~> 4.0)
|
||||||
|
@ -755,18 +751,17 @@ DEPENDENCIES
|
||||||
stackprof
|
stackprof
|
||||||
stoplight (~> 2.1.3)
|
stoplight (~> 2.1.3)
|
||||||
streamio-ffmpeg (~> 3.0)
|
streamio-ffmpeg (~> 3.0)
|
||||||
strong_migrations (~> 0.3)
|
strong_migrations (~> 0.2)
|
||||||
thor (~> 0.20)
|
|
||||||
tty-command (~> 0.8)
|
tty-command (~> 0.8)
|
||||||
tty-prompt (~> 0.17)
|
tty-prompt (~> 0.16)
|
||||||
twitter-text (~> 1.14)
|
twitter-text (~> 1.14)
|
||||||
tzinfo-data (~> 1.2018)
|
tzinfo-data (~> 1.2018)
|
||||||
webmock (~> 3.4)
|
webmock (~> 3.3)
|
||||||
webpacker (~> 3.5)
|
webpacker (~> 3.4)
|
||||||
webpush
|
webpush
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
ruby 2.5.3p105
|
ruby 2.5.0p0
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.16.6
|
1.16.3
|
||||||
|
|
95
README.md
|
@ -1,95 +1,96 @@
|
||||||
![Mastodon](https://i.imgur.com/NhZc40l.png)
|
![Mastodon](https://i.imgur.com/NhZc40l.png)
|
||||||
========
|
========
|
||||||
|
|
||||||
[![GitHub release](https://img.shields.io/github/release/tootsuite/mastodon.svg)][releases]
|
|
||||||
[![Build Status](https://img.shields.io/circleci/project/github/tootsuite/mastodon.svg)][circleci]
|
[![Build Status](https://img.shields.io/circleci/project/github/tootsuite/mastodon.svg)][circleci]
|
||||||
[![Code Climate](https://img.shields.io/codeclimate/maintainability/tootsuite/mastodon.svg)][code_climate]
|
[![Code Climate](https://img.shields.io/codeclimate/maintainability/tootsuite/mastodon.svg)][code_climate]
|
||||||
[![Translation status](https://weblate.joinmastodon.org/widgets/mastodon/-/svg-badge.svg)][weblate]
|
|
||||||
[![Docker Pulls](https://img.shields.io/docker/pulls/tootsuite/mastodon.svg)][docker]
|
|
||||||
|
|
||||||
[releases]: https://github.com/tootsuite/mastodon/releases
|
|
||||||
[circleci]: https://circleci.com/gh/tootsuite/mastodon
|
[circleci]: https://circleci.com/gh/tootsuite/mastodon
|
||||||
[code_climate]: https://codeclimate.com/github/tootsuite/mastodon
|
[code_climate]: https://codeclimate.com/github/tootsuite/mastodon
|
||||||
[weblate]: https://weblate.joinmastodon.org/engage/mastodon/
|
|
||||||
[docker]: https://hub.docker.com/r/tootsuite/mastodon/
|
|
||||||
|
|
||||||
Mastodon is a **free, open-source social network server** based on ActivityPub. Follow friends and discover new ones. Publish anything you want: links, pictures, text, video. All servers of Mastodon are interoperable as a federated network, i.e. users on one server can seamlessly communicate with users from another one. This includes non-Mastodon software that also implements ActivityPub!
|
Mastodon is a **free, open-source social network server** based on **open web protocols** like ActivityPub and OStatus. The social focus of the project is a viable decentralized alternative to commercial social media silos that returns the control of the content distribution channels to the people. The technical focus of the project is a good user interface, a clean REST API for 3rd party apps and robust anti-abuse tools.
|
||||||
|
|
||||||
Click below to **learn more** in a video:
|
Click on the screenshot below to watch a demo of the UI:
|
||||||
|
|
||||||
[![Screenshot](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/ezgif-2-60f1b00403.gif)][youtube_demo]
|
[![Screenshot](https://i.imgur.com/qrNOiSp.png)][youtube_demo]
|
||||||
|
|
||||||
[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
|
[youtube_demo]: https://www.youtube.com/watch?v=IPSbNdBmWKE
|
||||||
|
|
||||||
## Navigation
|
**Ruby on Rails** is used for the back-end, while **React.js** and Redux are used for the dynamic front-end. A static front-end for public resources (profiles and statuses) is also provided.
|
||||||
|
|
||||||
- [Project homepage 🐘](https://joinmastodon.org)
|
If you would like, you can [support the development of this project on Patreon][patreon] or [Liberapay][liberapay].
|
||||||
- [Support the development via Patreon][patreon]
|
|
||||||
- [View sponsors](https://joinmastodon.org/sponsors)
|
|
||||||
- [Blog](https://blog.joinmastodon.org)
|
|
||||||
- [Documentation](https://docs.joinmastodon.org)
|
|
||||||
- [Browse Mastodon servers](https://joinmastodon.org/#getting-started)
|
|
||||||
- [Browse Mastodon apps](https://joinmastodon.org/apps)
|
|
||||||
|
|
||||||
[patreon]: https://www.patreon.com/mastodon
|
[patreon]: https://www.patreon.com/user?u=619786
|
||||||
|
[liberapay]: https://liberapay.com/Mastodon/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- [Frequently Asked Questions](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/FAQ.md)
|
||||||
|
- [Use this tool to find Twitter friends on Mastodon](https://bridge.joinmastodon.org)
|
||||||
|
- [API overview](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md)
|
||||||
|
- [List of Mastodon instances](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/List-of-Mastodon-instances.md)
|
||||||
|
- [List of apps](https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md)
|
||||||
|
- [List of sponsors](https://joinmastodon.org/sponsors)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
<img src="https://docs.joinmastodon.org/elephant.svg" align="right" width="30%" />
|
|
||||||
|
|
||||||
**No vendor lock-in: Fully interoperable with any conforming platform**
|
**No vendor lock-in: Fully interoperable with any conforming platform**
|
||||||
|
|
||||||
It doesn't have to be Mastodon, whatever implements ActivityPub is part of the social network! [Learn more](https://blog.joinmastodon.org/2018/06/why-activitypub-is-the-future/)
|
It doesn't have to be Mastodon, whatever implements ActivityPub or OStatus is part of the social network!
|
||||||
|
|
||||||
**Real-time, chronological timeline updates**
|
**Real-time timeline updates**
|
||||||
|
|
||||||
See the updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!
|
See the updates of people you're following appear in real-time in the UI via WebSockets. There's a firehose view as well!
|
||||||
|
|
||||||
|
**Federated thread resolving**
|
||||||
|
|
||||||
|
If someone you follow replies to a user unknown to the server, the server fetches the full thread so you can view it without leaving the UI
|
||||||
|
|
||||||
**Media attachments like images and short videos**
|
**Media attachments like images and short videos**
|
||||||
|
|
||||||
Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos are looped - like vines!
|
Upload and view images and WebM/MP4 videos attached to the updates. Videos with no audio track are treated like GIFs; normal videos are looped - like vines!
|
||||||
|
|
||||||
**Safety and moderation tools**
|
|
||||||
|
|
||||||
Private posts, locked accounts, phrase filtering, muting, blocking and all sorts of other features, along with a reporting and moderation system. [Learn more](https://blog.joinmastodon.org/2018/07/cage-the-mastodon/)
|
|
||||||
|
|
||||||
**OAuth2 and a straightforward REST API**
|
**OAuth2 and a straightforward REST API**
|
||||||
|
|
||||||
Mastodon acts as an OAuth2 provider so 3rd party apps can use the REST and Streaming APIs, resulting in a rich app ecosystem with a lot of choice!
|
Mastodon acts as an OAuth2 provider so 3rd party apps can use the API
|
||||||
|
|
||||||
|
**Fast response times**
|
||||||
|
|
||||||
|
Mastodon tries to be as fast and responsive as possible, so all long-running tasks are delegated to background processing
|
||||||
|
|
||||||
|
**Deployable via Docker**
|
||||||
|
|
||||||
|
You don't need to mess with dependencies and configuration if you want to try Mastodon, if you have Docker and Docker Compose the deployment is extremely easy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
Please follow the [development guide](https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Development-guide.md) from the documentation repository.
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
**Tech stack:**
|
There are guides in the documentation repository for [deploying on various platforms](https://github.com/tootsuite/documentation#running-mastodon).
|
||||||
|
|
||||||
- **Ruby on Rails** powers the REST API and other web pages
|
|
||||||
- **React.js** and Redux are used for the dynamic parts of the interface
|
|
||||||
- **Node.js** powers the streaming API
|
|
||||||
|
|
||||||
**Requirements:**
|
|
||||||
|
|
||||||
- **PostgreSQL** 9.5+
|
|
||||||
- **Redis**
|
|
||||||
- **Ruby** 2.4+
|
|
||||||
- **Node.js** 8+
|
|
||||||
|
|
||||||
The repository includes deployment configurations for **Docker and docker-compose**, but also a few specific platforms like **Heroku**, **Scalingo**, and **Nanobox**. The [**stand-alone** installation guide](https://docs.joinmastodon.org/administration/installation/) is available in the documentation.
|
|
||||||
|
|
||||||
A **Vagrant** configuration is included for development purposes.
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Mastodon is **free, open source software** licensed under **AGPLv3**.
|
You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository. [Here are the guidelines for code contributions](CONTRIBUTING.md)
|
||||||
|
|
||||||
You can open issues for bugs you've found or features you think are missing. You can also submit pull requests to this repository, or submit translations using Weblate. To get started, take a look at [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
||||||
|
|
||||||
**IRC channel**: #mastodon on irc.freenode.net
|
**IRC channel**: #mastodon on irc.freenode.net
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Copyright (C) 2016-2018 Eugen Rochko & other Mastodon contributors (see [AUTHORS.md](AUTHORS.md))
|
Copyright (C) 2016-2018 Eugen Rochko & other Mastodon contributors (see AUTHORS.md)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Extra credits
|
||||||
|
|
||||||
|
The elephant friend illustrations are created by [Dopatwo](https://mastodon.social/@dopatwo)
|
||||||
|
|
|
@ -12,7 +12,7 @@ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
|
||||||
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
sudo apt-add-repository 'deb https://dl.yarnpkg.com/debian/ stable main'
|
||||||
|
|
||||||
# Add repo for NodeJS
|
# Add repo for NodeJS
|
||||||
curl -sL https://deb.nodesource.com/setup_8.x | sudo bash -
|
curl -sL https://deb.nodesource.com/setup_6.x | sudo bash -
|
||||||
|
|
||||||
# Add firewall rule to redirect 80 to PORT and save
|
# Add firewall rule to redirect 80 to PORT and save
|
||||||
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port #{ENV["PORT"]}
|
||||||
|
@ -85,9 +85,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
config.vm.provider :virtualbox do |vb|
|
config.vm.provider :virtualbox do |vb|
|
||||||
vb.name = "mastodon"
|
vb.name = "mastodon"
|
||||||
vb.customize ["modifyvm", :id, "--memory", "2048"]
|
vb.customize ["modifyvm", :id, "--memory", "2048"]
|
||||||
# Increase the number of CPUs. Uncomment and adjust to
|
|
||||||
# increase performance
|
|
||||||
# vb.customize ["modifyvm", :id, "--cpus", "3"]
|
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -100,22 +97,19 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
config.vm.hostname = "mastodon.dev"
|
||||||
|
|
||||||
# This uses the vagrant-hostsupdater plugin, and lets you
|
# This uses the vagrant-hostsupdater plugin, and lets you
|
||||||
# access the development site at http://mastodon.local.
|
# access the development site at http://mastodon.dev.
|
||||||
# If you change it, also change it in .env.vagrant before provisioning
|
|
||||||
# the vagrant server to update the development build.
|
|
||||||
#
|
|
||||||
# To install:
|
# To install:
|
||||||
# $ vagrant plugin install vagrant-hostsupdater
|
# $ vagrant plugin install vagrant-hostsupdater
|
||||||
config.vm.hostname = "mastodon.local"
|
|
||||||
|
|
||||||
if defined?(VagrantPlugins::HostsUpdater)
|
if defined?(VagrantPlugins::HostsUpdater)
|
||||||
config.vm.network :private_network, ip: "192.168.42.42", nictype: "virtio"
|
config.vm.network :private_network, ip: "192.168.42.42", nictype: "virtio"
|
||||||
config.hostsupdater.remove_on_suspend = false
|
config.hostsupdater.remove_on_suspend = false
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.vm.networks.any? { |type, options| type == :private_network }
|
if config.vm.networks.any? { |type, options| type == :private_network }
|
||||||
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp', 'actimeo=1']
|
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp']
|
||||||
else
|
else
|
||||||
config.vm.synced_folder ".", "/vagrant"
|
config.vm.synced_folder ".", "/vagrant"
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,7 +31,7 @@ class StatusesIndex < Chewy::Index
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
define_type ::Status.unscoped.without_reblogs do
|
define_type ::Status.without_reblogs do
|
||||||
crutch :mentions do |collection|
|
crutch :mentions do |collection|
|
||||||
data = ::Mention.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
|
data = ::Mention.where(status_id: collection.map(&:id)).pluck(:status_id, :account_id)
|
||||||
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
data.each.with_object({}) { |(id, name), result| (result[id] ||= []).push(name) }
|
||||||
|
|
|
@ -9,13 +9,9 @@ class AboutController < ApplicationController
|
||||||
@initial_state_json = serializable_resource.to_json
|
@initial_state_json = serializable_resource.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
def more
|
def more; end
|
||||||
render layout: 'public'
|
|
||||||
end
|
|
||||||
|
|
||||||
def terms
|
def terms; end
|
||||||
render layout: 'public'
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -30,7 +26,7 @@ class AboutController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'with-modals'
|
@body_classes = 'about-body'
|
||||||
end
|
end
|
||||||
|
|
||||||
def initial_state_params
|
def initial_state_params
|
||||||
|
|
|
@ -10,9 +10,7 @@ class AccountsController < ApplicationController
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
@body_classes = 'with-modals'
|
@pinned_statuses = []
|
||||||
@pinned_statuses = []
|
|
||||||
@endorsed_accounts = @account.endorsed_accounts.to_a.sample(4)
|
|
||||||
|
|
||||||
if current_account && @account.blocking?(current_account)
|
if current_account && @account.blocking?(current_account)
|
||||||
@statuses = []
|
@statuses = []
|
||||||
|
@ -42,7 +40,7 @@ class AccountsController < ApplicationController
|
||||||
format.json do
|
format.json do
|
||||||
skip_session!
|
skip_session!
|
||||||
|
|
||||||
render_cached_json(['activitypub', 'actor', @account], content_type: 'application/activity+json') do
|
render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do
|
||||||
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
|
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,7 +50,7 @@ class AccountsController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def show_pinned_statuses?
|
def show_pinned_statuses?
|
||||||
[replies_requested?, media_requested?, params[:max_id].present?, params[:min_id].present?].none?
|
[replies_requested?, media_requested?, params[:max_id].present?, params[:since_id].present?].none?
|
||||||
end
|
end
|
||||||
|
|
||||||
def filtered_statuses
|
def filtered_statuses
|
||||||
|
|
|
@ -36,6 +36,6 @@ class ActivityPub::InboxesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_payload
|
def process_payload
|
||||||
ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'), @account&.id)
|
ActivityPub::ProcessingWorker.perform_async(signed_request_account.id, body.force_encoding('UTF-8'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -95,7 +95,7 @@ module Admin
|
||||||
:remote,
|
:remote,
|
||||||
:by_domain,
|
:by_domain,
|
||||||
:silenced,
|
:silenced,
|
||||||
:alphabetic,
|
:recent,
|
||||||
:suspended,
|
:suspended,
|
||||||
:username,
|
:username,
|
||||||
:display_name,
|
:display_name,
|
||||||
|
|
|
@ -5,15 +5,8 @@ module Admin
|
||||||
include Authorization
|
include Authorization
|
||||||
include AccountableConcern
|
include AccountableConcern
|
||||||
|
|
||||||
layout 'admin'
|
|
||||||
|
|
||||||
before_action :require_staff!
|
before_action :require_staff!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
private
|
layout 'admin'
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
require 'sidekiq/api'
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class DashboardController < BaseController
|
|
||||||
def index
|
|
||||||
@users_count = User.count
|
|
||||||
@registrations_week = Redis.current.get("activity:accounts:local:#{current_week}") || 0
|
|
||||||
@logins_week = Redis.current.pfcount("activity:logins:#{current_week}")
|
|
||||||
@interactions_week = Redis.current.get("activity:interactions:#{current_week}") || 0
|
|
||||||
@relay_enabled = Relay.enabled.exists?
|
|
||||||
@single_user_mode = Rails.configuration.x.single_user_mode
|
|
||||||
@registrations_enabled = Setting.open_registrations
|
|
||||||
@deletions_enabled = Setting.open_deletion
|
|
||||||
@invites_enabled = Setting.min_invite_role == 'user'
|
|
||||||
@search_enabled = Chewy.enabled?
|
|
||||||
@version = Mastodon::Version.to_s
|
|
||||||
@database_version = ActiveRecord::Base.connection.execute('SELECT VERSION()').first['version'].match(/\A(?:PostgreSQL |)([^\s]+).*\z/)[1]
|
|
||||||
@redis_version = redis_info['redis_version']
|
|
||||||
@reports_count = Report.unresolved.count
|
|
||||||
@queue_backlog = Sidekiq::Stats.new.enqueued
|
|
||||||
@recent_users = User.confirmed.recent.includes(:account).limit(4)
|
|
||||||
@database_size = ActiveRecord::Base.connection.execute('SELECT pg_database_size(current_database())').first['pg_database_size']
|
|
||||||
@redis_size = redis_info['used_memory']
|
|
||||||
@ldap_enabled = ENV['LDAP_ENABLED'] == 'true'
|
|
||||||
@cas_enabled = ENV['CAS_ENABLED'] == 'true'
|
|
||||||
@saml_enabled = ENV['SAML_ENABLED'] == 'true'
|
|
||||||
@pam_enabled = ENV['PAM_ENABLED'] == 'true'
|
|
||||||
@hidden_service = ENV['ALLOW_ACCESS_TO_HIDDEN_SERVICE'] == 'true'
|
|
||||||
@trending_hashtags = TrendingTags.get(7)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def current_week
|
|
||||||
@current_week ||= Time.now.utc.to_date.cweek
|
|
||||||
end
|
|
||||||
|
|
||||||
def redis_info
|
|
||||||
@redis_info ||= Redis.current.info
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -46,7 +46,7 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :retroactive)
|
params.require(:domain_block).permit(:domain, :severity, :reject_media, :retroactive)
|
||||||
end
|
end
|
||||||
|
|
||||||
def retroactive_unblock?
|
def retroactive_unblock?
|
||||||
|
|
|
@ -30,12 +30,6 @@ module Admin
|
||||||
redirect_to admin_invites_path
|
redirect_to admin_invites_path
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate_all
|
|
||||||
authorize :invite, :deactivate_all?
|
|
||||||
Invite.available.in_batches.update_all(expires_at: Time.now.utc)
|
|
||||||
redirect_to admin_invites_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module Admin
|
|
||||||
class RelaysController < BaseController
|
|
||||||
before_action :set_relay, except: [:index, :new, :create]
|
|
||||||
|
|
||||||
def index
|
|
||||||
authorize :relay, :update?
|
|
||||||
@relays = Relay.all
|
|
||||||
end
|
|
||||||
|
|
||||||
def new
|
|
||||||
authorize :relay, :update?
|
|
||||||
@relay = Relay.new(inbox_url: Relay::PRESET_RELAY)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
authorize :relay, :update?
|
|
||||||
|
|
||||||
@relay = Relay.new(resource_params)
|
|
||||||
|
|
||||||
if @relay.save
|
|
||||||
@relay.enable!
|
|
||||||
redirect_to admin_relays_path
|
|
||||||
else
|
|
||||||
render action: :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
authorize :relay, :update?
|
|
||||||
@relay.destroy
|
|
||||||
redirect_to admin_relays_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def enable
|
|
||||||
authorize :relay, :update?
|
|
||||||
@relay.enable!
|
|
||||||
redirect_to admin_relays_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def disable
|
|
||||||
authorize :relay, :update?
|
|
||||||
@relay.disable!
|
|
||||||
redirect_to admin_relays_path
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_relay
|
|
||||||
@relay = Relay.find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.require(:relay).permit(:inbox_url)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -44,16 +44,14 @@ module Admin
|
||||||
when 'resolve'
|
when 'resolve'
|
||||||
@report.resolve!(current_account)
|
@report.resolve!(current_account)
|
||||||
log_action :resolve, @report
|
log_action :resolve, @report
|
||||||
when 'disable'
|
when 'suspend'
|
||||||
@report.resolve!(current_account)
|
Admin::SuspensionWorker.perform_async(@report.target_account.id)
|
||||||
@report.target_account.user.disable!
|
|
||||||
|
|
||||||
log_action :resolve, @report
|
log_action :resolve, @report
|
||||||
log_action :disable, @report.target_account.user
|
log_action :suspend, @report.target_account
|
||||||
|
|
||||||
resolve_all_target_account_reports
|
resolve_all_target_account_reports
|
||||||
when 'silence'
|
when 'silence'
|
||||||
@report.resolve!(current_account)
|
|
||||||
@report.target_account.update!(silenced: true)
|
@report.target_account.update!(silenced: true)
|
||||||
|
|
||||||
log_action :resolve, @report
|
log_action :resolve, @report
|
||||||
|
@ -63,7 +61,6 @@ module Admin
|
||||||
else
|
else
|
||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
@report.reload
|
@report.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ module Admin
|
||||||
site_contact_username
|
site_contact_username
|
||||||
site_contact_email
|
site_contact_email
|
||||||
site_title
|
site_title
|
||||||
site_short_description
|
|
||||||
site_description
|
site_description
|
||||||
site_extended_description
|
site_extended_description
|
||||||
site_terms
|
site_terms
|
||||||
|
@ -16,16 +15,13 @@ module Admin
|
||||||
timeline_preview
|
timeline_preview
|
||||||
show_staff_badge
|
show_staff_badge
|
||||||
bootstrap_timeline_accounts
|
bootstrap_timeline_accounts
|
||||||
theme
|
|
||||||
thumbnail
|
thumbnail
|
||||||
hero
|
hero
|
||||||
mascot
|
|
||||||
min_invite_role
|
min_invite_role
|
||||||
activity_api_enabled
|
activity_api_enabled
|
||||||
peers_api_enabled
|
peers_api_enabled
|
||||||
show_known_fediverse_at_about_page
|
show_known_fediverse_at_about_page
|
||||||
preview_sensitive_media
|
preview_sensitive_media
|
||||||
custom_css
|
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
BOOLEAN_SETTINGS = %w(
|
BOOLEAN_SETTINGS = %w(
|
||||||
|
@ -42,7 +38,6 @@ module Admin
|
||||||
UPLOAD_SETTINGS = %w(
|
UPLOAD_SETTINGS = %w(
|
||||||
thumbnail
|
thumbnail
|
||||||
hero
|
hero
|
||||||
mascot
|
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
|
|
@ -28,10 +28,6 @@ module Admin
|
||||||
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
|
@form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save
|
||||||
|
|
||||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
|
||||||
rescue ActionController::ParameterMissing
|
|
||||||
flash[:alert] = I18n.t('admin.statuses.no_status_selected')
|
|
||||||
|
|
||||||
redirect_to admin_account_statuses_path(@account.id, current_params)
|
redirect_to admin_account_statuses_path(@account.id, current_params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,24 +4,11 @@ module Admin
|
||||||
class SuspensionsController < BaseController
|
class SuspensionsController < BaseController
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
|
|
||||||
def new
|
|
||||||
@suspension = Form::AdminSuspensionConfirmation.new(report_id: params[:report_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
authorize @account, :suspend?
|
authorize @account, :suspend?
|
||||||
|
Admin::SuspensionWorker.perform_async(@account.id)
|
||||||
@suspension = Form::AdminSuspensionConfirmation.new(suspension_params)
|
log_action :suspend, @account
|
||||||
|
redirect_to admin_accounts_path
|
||||||
if suspension_params[:acct] == @account.acct
|
|
||||||
resolve_report! if suspension_params[:report_id].present?
|
|
||||||
perform_suspend!
|
|
||||||
mark_reports_resolved!
|
|
||||||
redirect_to admin_accounts_path
|
|
||||||
else
|
|
||||||
flash.now[:alert] = I18n.t('admin.suspensions.bad_acct_msg')
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
@ -36,25 +23,5 @@ module Admin
|
||||||
def set_account
|
def set_account
|
||||||
@account = Account.find(params[:account_id])
|
@account = Account.find(params[:account_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def suspension_params
|
|
||||||
params.require(:form_admin_suspension_confirmation).permit(:acct, :report_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def resolve_report!
|
|
||||||
report = Report.find(suspension_params[:report_id])
|
|
||||||
report.resolve!(current_account)
|
|
||||||
log_action :resolve, report
|
|
||||||
end
|
|
||||||
|
|
||||||
def perform_suspend!
|
|
||||||
@account.suspend!
|
|
||||||
Admin::SuspensionWorker.perform_async(@account.id)
|
|
||||||
log_action :suspend, @account
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_reports_resolved!
|
|
||||||
Report.where(target_account: @account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,8 +7,6 @@ class Api::BaseController < ApplicationController
|
||||||
include RateLimitHeaders
|
include RateLimitHeaders
|
||||||
|
|
||||||
skip_before_action :store_current_location
|
skip_before_action :store_current_location
|
||||||
skip_before_action :check_user_permissions
|
|
||||||
|
|
||||||
protect_from_forgery with: :null_session
|
protect_from_forgery with: :null_session
|
||||||
|
|
||||||
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
||||||
|
@ -53,8 +51,8 @@ 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 params_slice(*keys)
|
def truthy_param?(key)
|
||||||
params.slice(*keys).permit(*keys)
|
ActiveModel::Type::Boolean.new.cast(params[key])
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_resource_owner
|
def current_resource_owner
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::Accounts::PinsController < Api::BaseController
|
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_account
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def create
|
|
||||||
AccountPin.create!(account: current_account, target_account: @account)
|
|
||||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
pin = AccountPin.find_by(account: current_account, target_account: @account)
|
|
||||||
pin&.destroy!
|
|
||||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_account
|
|
||||||
@account = Account.find(params[:account_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def relationships_presenter
|
|
||||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -28,9 +28,10 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||||
|
|
||||||
def account_statuses
|
def account_statuses
|
||||||
statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses
|
statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses
|
||||||
statuses = statuses.paginate_by_id(
|
statuses = statuses.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params[:max_id],
|
||||||
|
params[:since_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
|
statuses.merge!(only_media_scope) if truthy_param?(:only_media)
|
||||||
|
@ -81,7 +82,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
unless @statuses.empty?
|
unless @statuses.empty?
|
||||||
api_v1_account_statuses_url pagination_params(min_id: pagination_since_id)
|
api_v1_account_statuses_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::ConversationsController < Api::BaseController
|
|
||||||
LIMIT = 20
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :index
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:conversations' }, except: :index
|
|
||||||
before_action :require_user!
|
|
||||||
before_action :set_conversation, except: :index
|
|
||||||
after_action :insert_pagination_headers, only: :index
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def index
|
|
||||||
@conversations = paginated_conversations
|
|
||||||
render json: @conversations, each_serializer: REST::ConversationSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
def read
|
|
||||||
@conversation.update!(unread: false)
|
|
||||||
render json: @conversation, serializer: REST::ConversationSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@conversation.destroy!
|
|
||||||
render_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_conversation
|
|
||||||
@conversation = AccountConversation.where(account: current_account).find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def paginated_conversations
|
|
||||||
AccountConversation.where(account: current_account)
|
|
||||||
.paginate_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
|
||||||
end
|
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
|
||||||
if records_continue?
|
|
||||||
api_v1_conversations_url pagination_params(max_id: pagination_max_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def prev_path
|
|
||||||
unless @conversations.empty?
|
|
||||||
api_v1_conversations_url pagination_params(min_id: pagination_since_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_max_id
|
|
||||||
@conversations.last.last_status_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_since_id
|
|
||||||
@conversations.first.last_status_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def records_continue?
|
|
||||||
@conversations.size == limit_param(LIMIT)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,72 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Api::V1::EndorsementsController < Api::BaseController
|
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }
|
|
||||||
before_action :require_user!
|
|
||||||
after_action :insert_pagination_headers
|
|
||||||
|
|
||||||
respond_to :json
|
|
||||||
|
|
||||||
def index
|
|
||||||
@accounts = load_accounts
|
|
||||||
render json: @accounts, each_serializer: REST::AccountSerializer
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def load_accounts
|
|
||||||
if unlimited?
|
|
||||||
endorsed_accounts.all
|
|
||||||
else
|
|
||||||
endorsed_accounts.paginate_by_max_id(
|
|
||||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
|
||||||
params[:max_id],
|
|
||||||
params[:since_id]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def endorsed_accounts
|
|
||||||
current_account.endorsed_accounts
|
|
||||||
end
|
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
|
||||||
return if unlimited?
|
|
||||||
|
|
||||||
if records_continue?
|
|
||||||
api_v1_endorsements_url pagination_params(max_id: pagination_max_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def prev_path
|
|
||||||
return if unlimited?
|
|
||||||
|
|
||||||
unless @accounts.empty?
|
|
||||||
api_v1_endorsements_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
|
|
|
@ -26,9 +26,10 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def results
|
def results
|
||||||
@_results ||= account_favourites.paginate_by_id(
|
@_results ||= account_favourites.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params[:max_id],
|
||||||
|
params[:since_id]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ class Api::V1::FavouritesController < Api::BaseController
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
unless results.empty?
|
unless results.empty?
|
||||||
api_v1_favourites_url pagination_params(min_id: pagination_since_id)
|
api_v1_favourites_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ class Api::V1::FollowRequestsController < Api::BaseController
|
||||||
|
|
||||||
def authorize
|
def authorize
|
||||||
AuthorizeFollowService.new.call(account, current_account)
|
AuthorizeFollowService.new.call(account, current_account)
|
||||||
NotifyService.new.call(current_account, Follow.find_by(account: account, target_account: current_account))
|
|
||||||
render_empty
|
render_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,6 @@ class Api::V1::InstancesController < Api::BaseController
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render_cached_json('api:v1:instances', expires_in: 5.minutes) do
|
render json: {}, serializer: REST::InstanceSerializer
|
||||||
ActiveModelSerializers::SerializableResource.new({}, serializer: REST::InstanceSerializer)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Lists::AccountsController < Api::BaseController
|
class Api::V1::Lists::AccountsController < Api::BaseController
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:show]
|
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:show]
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:show]
|
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:show]
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::ListsController < Api::BaseController
|
class Api::V1::ListsController < Api::BaseController
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index, :show]
|
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index, :show]
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:index, :show]
|
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:index, :show]
|
||||||
|
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|
|
@ -15,17 +15,19 @@ class Api::V1::MutesController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def load_accounts
|
def load_accounts
|
||||||
paginated_mutes.map(&:target_account)
|
default_accounts.merge(paginated_mutes).to_a
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_accounts
|
||||||
|
Account.includes(:muted_by).references(:muted_by)
|
||||||
end
|
end
|
||||||
|
|
||||||
def paginated_mutes
|
def paginated_mutes
|
||||||
@paginated_mutes ||= Mute.eager_load(:target_account)
|
Mute.where(account: current_account).paginate_by_max_id(
|
||||||
.where(account: current_account)
|
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||||
.paginate_by_max_id(
|
params[:max_id],
|
||||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
params[:since_id]
|
||||||
params[:max_id],
|
)
|
||||||
params[:since_id]
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
def insert_pagination_headers
|
||||||
|
@ -39,21 +41,21 @@ class Api::V1::MutesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
unless paginated_mutes.empty?
|
unless @accounts.empty?
|
||||||
api_v1_mutes_url pagination_params(since_id: pagination_since_id)
|
api_v1_mutes_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_max_id
|
def pagination_max_id
|
||||||
paginated_mutes.last.id
|
@accounts.last.muted_by_ids.last
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_since_id
|
def pagination_since_id
|
||||||
paginated_mutes.first.id
|
@accounts.first.muted_by_ids.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def records_continue?
|
def records_continue?
|
||||||
paginated_mutes.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)
|
||||||
|
|
|
@ -37,9 +37,10 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def paginated_notifications
|
def paginated_notifications
|
||||||
browserable_account_notifications.paginate_by_id(
|
browserable_account_notifications.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
|
limit_param(DEFAULT_NOTIFICATIONS_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params[:max_id],
|
||||||
|
params[:since_id]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
unless @notifications.empty?
|
unless @notifications.empty?
|
||||||
api_v1_notifications_url pagination_params(min_id: pagination_since_id)
|
api_v1_notifications_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::ReportsController < Api::BaseController
|
class Api::V1::ReportsController < Api::BaseController
|
||||||
|
before_action -> { doorkeeper_authorize! :read, :'read:reports' }, except: [:create]
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
|
before_action -> { doorkeeper_authorize! :write, :'write:reports' }, only: [:create]
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|
||||||
respond_to :json
|
respond_to :json
|
||||||
|
|
||||||
|
def index
|
||||||
|
@reports = current_account.reports
|
||||||
|
render json: @reports, each_serializer: REST::ReportSerializer
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@report = ReportService.new.call(
|
@report = ReportService.new.call(
|
||||||
current_account,
|
current_account,
|
||||||
|
@ -21,7 +27,7 @@ class Api::V1::ReportsController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def reported_status_ids
|
def reported_status_ids
|
||||||
reported_account.statuses.find(status_ids).pluck(:id)
|
Status.find(status_ids).pluck(:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def status_ids
|
def status_ids
|
||||||
|
|
|
@ -17,7 +17,8 @@ class Api::V1::StatusesController < Api::BaseController
|
||||||
CONTEXT_LIMIT = 4_096
|
CONTEXT_LIMIT = 4_096
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@status = cache_collection([@status], Status).first
|
cached = Rails.cache.read(@status.cache_key)
|
||||||
|
@status = cached unless cached.nil?
|
||||||
render json: @status, serializer: REST::StatusSerializer
|
render json: @status, serializer: REST::StatusSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
account_home_feed.get(
|
account_home_feed.get(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params[:max_id],
|
params[:max_id],
|
||||||
params[:since_id],
|
params[:since_id]
|
||||||
params[:min_id]
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_home_url pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_home_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_max_id
|
def pagination_max_id
|
||||||
|
|
|
@ -32,8 +32,7 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||||
list_feed.get(
|
list_feed.get(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params[:max_id],
|
params[:max_id],
|
||||||
params[:since_id],
|
params[:since_id]
|
||||||
params[:min_id]
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -54,7 +53,7 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_list_url params[:id], pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_list_url params[:id], pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_max_id
|
def pagination_max_id
|
||||||
|
|
|
@ -21,9 +21,10 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_statuses
|
def public_statuses
|
||||||
statuses = public_timeline_statuses.paginate_by_id(
|
statuses = public_timeline_statuses.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params[:max_id],
|
||||||
|
params[:since_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
if truthy_param?(:only_media)
|
if truthy_param?(:only_media)
|
||||||
|
@ -52,7 +53,7 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_public_url pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_public_url pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_max_id
|
def pagination_max_id
|
||||||
|
|
|
@ -29,9 +29,10 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||||
if @tag.nil?
|
if @tag.nil?
|
||||||
[]
|
[]
|
||||||
else
|
else
|
||||||
statuses = tag_timeline_statuses.paginate_by_id(
|
statuses = tag_timeline_statuses.paginate_by_max_id(
|
||||||
limit_param(DEFAULT_STATUSES_LIMIT),
|
limit_param(DEFAULT_STATUSES_LIMIT),
|
||||||
params_slice(:max_id, :since_id, :min_id)
|
params[:max_id],
|
||||||
|
params[:since_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
if truthy_param?(:only_media)
|
if truthy_param?(:only_media)
|
||||||
|
@ -61,7 +62,7 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_tag_url params[:id], pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_tag_url params[:id], pagination_params(since_id: pagination_since_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pagination_max_id
|
def pagination_max_id
|
||||||
|
|
|
@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base
|
||||||
rescue_from Mastodon::NotPermittedError, with: :forbidden
|
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_user_permissions, if: :user_signed_in?
|
before_action :check_suspension, if: :user_signed_in?
|
||||||
|
|
||||||
def raise_not_found
|
def raise_not_found
|
||||||
raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}"
|
raise ActionController::RoutingError, "No route matches #{params[:unmatched_route]}"
|
||||||
|
@ -48,8 +48,8 @@ class ApplicationController < ActionController::Base
|
||||||
forbidden unless current_user&.staff?
|
forbidden unless current_user&.staff?
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_user_permissions
|
def check_suspension
|
||||||
forbidden if current_user.disabled? || current_user.account.suspended?
|
forbidden if current_user.account.suspended?
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_sign_out_path_for(_resource_or_scope)
|
def after_sign_out_path_for(_resource_or_scope)
|
||||||
|
@ -58,10 +58,6 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def truthy_param?(key)
|
|
||||||
ActiveModel::Type::Boolean.new.cast(params[key])
|
|
||||||
end
|
|
||||||
|
|
||||||
def forbidden
|
def forbidden
|
||||||
respond_with_error(403)
|
respond_with_error(403)
|
||||||
end
|
end
|
||||||
|
@ -99,7 +95,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_theme
|
def current_theme
|
||||||
return Setting.theme unless Themes.instance.names.include? current_user&.setting_theme
|
return Setting.default_settings['theme'] unless Themes.instance.names.include? current_user&.setting_theme
|
||||||
current_user.setting_theme
|
current_user.setting_theme
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -107,8 +103,12 @@ class ApplicationController < ActionController::Base
|
||||||
return raw unless klass.respond_to?(:with_includes)
|
return raw unless klass.respond_to?(:with_includes)
|
||||||
|
|
||||||
raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation)
|
raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation)
|
||||||
cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id)
|
uncached_ids = []
|
||||||
uncached_ids = raw.map(&:id) - cached_keys_with_value.keys
|
cached_keys_with_value = Rails.cache.read_multi(*raw.map(&:cache_key))
|
||||||
|
|
||||||
|
raw.each do |item|
|
||||||
|
uncached_ids << item.id unless cached_keys_with_value.key?(item.cache_key)
|
||||||
|
end
|
||||||
|
|
||||||
klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!)
|
klass.reload_stale_associations!(cached_keys_with_value.values) if klass.respond_to?(:reload_stale_associations!)
|
||||||
|
|
||||||
|
@ -116,17 +116,16 @@ class ApplicationController < ActionController::Base
|
||||||
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.each_value do |item|
|
||||||
Rails.cache.write(item, item)
|
Rails.cache.write(item.cache_key, item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
raw.map { |item| cached_keys_with_value[item.id] || uncached[item.id] }.compact
|
raw.map { |item| cached_keys_with_value[item.cache_key] || uncached[item.id] }.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
def respond_with_error(code)
|
def respond_with_error(code)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.any { head code }
|
format.any { head code }
|
||||||
|
|
||||||
format.html do
|
format.html do
|
||||||
set_locale
|
set_locale
|
||||||
render "errors/#{code}", layout: 'error', status: code
|
render "errors/#{code}", layout: 'error', status: code
|
||||||
|
@ -136,6 +135,7 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
def render_cached_json(cache_key, **options)
|
def render_cached_json(cache_key, **options)
|
||||||
options[:expires_in] ||= 3.minutes
|
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
|
cache_public = options.key?(:public) ? options.delete(:public) : true
|
||||||
content_type = options.delete(:content_type) || 'application/json'
|
content_type = options.delete(:content_type) || 'application/json'
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
before_action :set_body_classes
|
|
||||||
before_action :set_user, only: [:finish_signup]
|
before_action :set_user, only: [:finish_signup]
|
||||||
|
|
||||||
# GET/PATCH /users/:id/finish_signup
|
# GET/PATCH /users/:id/finish_signup
|
||||||
|
@ -24,10 +23,6 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
@user = current_user
|
@user = current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'lighter'
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
params.require(:user).permit(:email)
|
params.require(:user).permit(:email)
|
||||||
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_body_classes
|
|
||||||
|
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
|
@ -15,10 +14,6 @@ class Auth::PasswordsController < Devise::PasswordsController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'lighter'
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -8,7 +8,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
before_action :configure_sign_up_params, only: [:create]
|
before_action :configure_sign_up_params, only: [:create]
|
||||||
before_action :set_sessions, only: [:edit, :update]
|
before_action :set_sessions, only: [:edit, :update]
|
||||||
before_action :set_instance_presenter, only: [:new, :create, :update]
|
before_action :set_instance_presenter, only: [:new, :create, :update]
|
||||||
before_action :set_body_classes, only: [:new, :create, :edit, :update]
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
not_found
|
not_found
|
||||||
|
@ -80,10 +79,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
@instance_presenter = InstancePresenter.new
|
@instance_presenter = InstancePresenter.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = %w(edit update).include?(action_name) ? 'admin' : 'lighter'
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_invite
|
def set_invite
|
||||||
@invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
|
@invite = invite_code.present? ? Invite.find_by(code: invite_code) : nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,10 +6,9 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
layout 'auth'
|
layout 'auth'
|
||||||
|
|
||||||
skip_before_action :require_no_authentication, only: [:create]
|
skip_before_action :require_no_authentication, only: [:create]
|
||||||
skip_before_action :check_user_permissions, 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]
|
||||||
before_action :set_instance_presenter, only: [:new]
|
before_action :set_instance_presenter, only: [:new]
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
Devise.omniauth_configs.each do |provider, config|
|
Devise.omniauth_configs.each do |provider, config|
|
||||||
|
@ -27,10 +26,8 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
tmp_stored_location = stored_location_for(:user)
|
|
||||||
super
|
super
|
||||||
flash.delete(:notice)
|
flash.delete(:notice)
|
||||||
store_location_for(:user, tmp_stored_location) if continue_after?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -112,10 +109,6 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
@instance_presenter = InstancePresenter.new
|
@instance_presenter = InstancePresenter.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'lighter'
|
|
||||||
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)
|
||||||
|
@ -123,8 +116,4 @@ class Auth::SessionsController < Devise::SessionsController
|
||||||
end
|
end
|
||||||
paths
|
paths
|
||||||
end
|
end
|
||||||
|
|
||||||
def continue_after?
|
|
||||||
truthy_param?(:continue)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AuthorizeFollowsController < ApplicationController
|
||||||
|
layout 'modal'
|
||||||
|
|
||||||
|
before_action :authenticate_user!
|
||||||
|
before_action :set_body_classes
|
||||||
|
|
||||||
|
def show
|
||||||
|
@account = located_account || render(:error)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@account = follow_attempt.try(:target_account)
|
||||||
|
|
||||||
|
if @account.nil?
|
||||||
|
render :error
|
||||||
|
else
|
||||||
|
render :success
|
||||||
|
end
|
||||||
|
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
||||||
|
render :error
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def follow_attempt
|
||||||
|
FollowService.new.call(current_account, acct_without_prefix)
|
||||||
|
end
|
||||||
|
|
||||||
|
def located_account
|
||||||
|
if acct_param_is_url?
|
||||||
|
account_from_remote_fetch
|
||||||
|
else
|
||||||
|
account_from_remote_follow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_from_remote_fetch
|
||||||
|
FetchRemoteAccountService.new.call(acct_without_prefix)
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_from_remote_follow
|
||||||
|
ResolveAccountService.new.call(acct_without_prefix)
|
||||||
|
end
|
||||||
|
|
||||||
|
def acct_param_is_url?
|
||||||
|
parsed_uri.path && %w(http https).include?(parsed_uri.scheme)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parsed_uri
|
||||||
|
Addressable::URI.parse(acct_without_prefix).normalize
|
||||||
|
end
|
||||||
|
|
||||||
|
def acct_without_prefix
|
||||||
|
acct_params.gsub(/\Aacct:/, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def acct_params
|
||||||
|
params.fetch(:acct, '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_body_classes
|
||||||
|
@body_classes = 'modal-layout'
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,66 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AuthorizeInteractionsController < ApplicationController
|
|
||||||
include Authorization
|
|
||||||
|
|
||||||
layout 'modal'
|
|
||||||
|
|
||||||
before_action :authenticate_user!
|
|
||||||
before_action :set_body_classes
|
|
||||||
before_action :set_resource
|
|
||||||
|
|
||||||
def show
|
|
||||||
if @resource.is_a?(Account)
|
|
||||||
render :show
|
|
||||||
elsif @resource.is_a?(Status)
|
|
||||||
redirect_to web_url("statuses/#{@resource.id}")
|
|
||||||
else
|
|
||||||
render :error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
if @resource.is_a?(Account) && FollowService.new.call(current_account, @resource)
|
|
||||||
render :success
|
|
||||||
else
|
|
||||||
render :error
|
|
||||||
end
|
|
||||||
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
|
||||||
render :error
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_resource
|
|
||||||
@resource = located_resource || render(:error)
|
|
||||||
authorize(@resource, :show?) if @resource.is_a?(Status)
|
|
||||||
end
|
|
||||||
|
|
||||||
def located_resource
|
|
||||||
if uri_param_is_url?
|
|
||||||
ResolveURLService.new.call(uri_param)
|
|
||||||
else
|
|
||||||
account_from_remote_follow
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_from_remote_follow
|
|
||||||
ResolveAccountService.new.call(uri_param)
|
|
||||||
end
|
|
||||||
|
|
||||||
def uri_param_is_url?
|
|
||||||
parsed_uri.path && %w(http https).include?(parsed_uri.scheme)
|
|
||||||
end
|
|
||||||
|
|
||||||
def parsed_uri
|
|
||||||
Addressable::URI.parse(uri_param).normalize
|
|
||||||
end
|
|
||||||
|
|
||||||
def uri_param
|
|
||||||
params[:uri] || params.fetch(:acct, '').gsub(/\Aacct:/, '')
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'modal-layout'
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -8,7 +8,6 @@ module AccountControllerConcern
|
||||||
included do
|
included do
|
||||||
layout 'public'
|
layout 'public'
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :set_instance_presenter
|
|
||||||
before_action :set_link_headers
|
before_action :set_link_headers
|
||||||
before_action :check_account_suspension
|
before_action :check_account_suspension
|
||||||
end
|
end
|
||||||
|
@ -19,10 +18,6 @@ module AccountControllerConcern
|
||||||
@account = Account.find_local!(params[:account_username])
|
@account = Account.find_local!(params[:account_username])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_instance_presenter
|
|
||||||
@instance_presenter = InstancePresenter.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_link_headers
|
def set_link_headers
|
||||||
response.headers['Link'] = LinkHeader.new(
|
response.headers['Link'] = LinkHeader.new(
|
||||||
[
|
[
|
||||||
|
|
|
@ -22,12 +22,6 @@ module SignatureVerification
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if request.headers['Date'].present? && !matches_time_window?
|
|
||||||
@signature_verification_failure_reason = 'Signed request date outside acceptable time window'
|
|
||||||
@signed_request_account = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
raw_signature = request.headers['Signature']
|
raw_signature = request.headers['Signature']
|
||||||
signature_params = {}
|
signature_params = {}
|
||||||
|
|
||||||
|
@ -82,7 +76,7 @@ module SignatureVerification
|
||||||
def build_signed_string(signed_headers)
|
def build_signed_string(signed_headers)
|
||||||
signed_headers = 'date' if signed_headers.blank?
|
signed_headers = 'date' if signed_headers.blank?
|
||||||
|
|
||||||
signed_headers.downcase.split(' ').map do |signed_header|
|
signed_headers.split(' ').map do |signed_header|
|
||||||
if signed_header == Request::REQUEST_TARGET
|
if signed_header == Request::REQUEST_TARGET
|
||||||
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
"#{Request::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
|
||||||
elsif signed_header == 'digest'
|
elsif signed_header == 'digest'
|
||||||
|
@ -95,12 +89,12 @@ module SignatureVerification
|
||||||
|
|
||||||
def matches_time_window?
|
def matches_time_window?
|
||||||
begin
|
begin
|
||||||
time_sent = Time.httpdate(request.headers['Date'])
|
time_sent = DateTime.httpdate(request.headers['Date'])
|
||||||
rescue ArgumentError
|
rescue ArgumentError
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
(Time.now.utc - time_sent).abs <= 12.hours
|
(Time.now.utc - time_sent).abs <= 30
|
||||||
end
|
end
|
||||||
|
|
||||||
def body_digest
|
def body_digest
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class CustomCssController < ApplicationController
|
|
||||||
before_action :set_cache_headers
|
|
||||||
|
|
||||||
def show
|
|
||||||
skip_session!
|
|
||||||
render plain: Setting.custom_css || '', content_type: 'text/css'
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -9,7 +9,7 @@ class EmojisController < ApplicationController
|
||||||
format.json do
|
format.json do
|
||||||
skip_session!
|
skip_session!
|
||||||
|
|
||||||
render_cached_json(['activitypub', 'emoji', @emoji], content_type: 'application/activity+json') do
|
render_cached_json(['activitypub', 'emoji', @emoji.cache_key], content_type: 'application/activity+json') do
|
||||||
ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter)
|
ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,6 @@ class FiltersController < ApplicationController
|
||||||
|
|
||||||
before_action :set_filters, only: :index
|
before_action :set_filters, only: :index
|
||||||
before_action :set_filter, only: [:edit, :update, :destroy]
|
before_action :set_filter, only: [:edit, :update, :destroy]
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@filters = current_account.custom_filters
|
@filters = current_account.custom_filters
|
||||||
|
@ -53,10 +52,6 @@ class FiltersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:custom_filter).permit(:phrase, :expires_in, :irreversible, :whole_word, context: [])
|
params.require(:custom_filter).permit(:phrase, :expires_in, :irreversible, context: [])
|
||||||
end
|
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,7 +58,7 @@ class HomeController < ApplicationController
|
||||||
if request.path.start_with?('/web')
|
if request.path.start_with?('/web')
|
||||||
new_user_session_path
|
new_user_session_path
|
||||||
elsif single_user_mode?
|
elsif single_user_mode?
|
||||||
short_account_path(Account.local.where(suspended: false).first)
|
short_account_path(Account.first)
|
||||||
else
|
else
|
||||||
about_path
|
about_path
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,7 @@ class IntentsController < ApplicationController
|
||||||
if uri.scheme == 'web+mastodon'
|
if uri.scheme == 'web+mastodon'
|
||||||
case uri.host
|
case uri.host
|
||||||
when 'follow'
|
when 'follow'
|
||||||
return redirect_to authorize_interaction_path(uri: uri.query_values['uri'].gsub(/\Aacct:/, ''))
|
return redirect_to authorize_follow_path(acct: uri.query_values['uri'].gsub(/\Aacct:/, ''))
|
||||||
when 'share'
|
when 'share'
|
||||||
return redirect_to share_path(text: uri.query_values['text'])
|
return redirect_to share_path(text: uri.query_values['text'])
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,6 @@ class InvitesController < ApplicationController
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :invite, :create?
|
authorize :invite, :create?
|
||||||
|
@ -39,14 +38,10 @@ class InvitesController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def invites
|
def invites
|
||||||
Invite.where(user: current_user).order(id: :desc)
|
Invite.where(user: current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def resource_params
|
def resource_params
|
||||||
params.require(:invite).permit(:max_uses, :expires_in, :autofollow)
|
params.require(:invite).permit(:max_uses, :expires_in, :autofollow)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,18 +13,4 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
||||||
def store_current_location
|
def store_current_location
|
||||||
store_location_for(:user, request.url)
|
store_location_for(:user, request.url)
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_success
|
|
||||||
if skip_authorization? || (matching_token? && !truthy_param?('force_login'))
|
|
||||||
redirect_or_render authorize_response
|
|
||||||
elsif Doorkeeper.configuration.api_only
|
|
||||||
render json: pre_auth
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def truthy_param?(key)
|
|
||||||
ActiveModel::Type::Boolean.new.cast(params[key])
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,6 +42,5 @@ class RemoteFollowController < ApplicationController
|
||||||
|
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'modal-layout'
|
@body_classes = 'modal-layout'
|
||||||
@hide_header = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class RemoteInteractionController < ApplicationController
|
|
||||||
include Authorization
|
|
||||||
|
|
||||||
layout 'modal'
|
|
||||||
|
|
||||||
before_action :set_status
|
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def new
|
|
||||||
@remote_follow = RemoteFollow.new(session_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
@remote_follow = RemoteFollow.new(resource_params)
|
|
||||||
|
|
||||||
if @remote_follow.valid?
|
|
||||||
session[:remote_follow] = @remote_follow.acct
|
|
||||||
redirect_to @remote_follow.interact_address_for(@status)
|
|
||||||
else
|
|
||||||
render :new
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def resource_params
|
|
||||||
params.require(:remote_follow).permit(:acct)
|
|
||||||
end
|
|
||||||
|
|
||||||
def session_params
|
|
||||||
{ acct: session[:remote_follow] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
# Reraise in order to get a 404
|
|
||||||
raise ActiveRecord::RecordNotFound
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'modal-layout'
|
|
||||||
@hide_header = true
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -6,7 +6,6 @@ class Settings::ApplicationsController < ApplicationController
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_application, only: [:show, :update, :destroy, :regenerate]
|
before_action :set_application, only: [:show, :update, :destroy, :regenerate]
|
||||||
before_action :prepare_scopes, only: [:create, :update]
|
before_action :prepare_scopes, only: [:create, :update]
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@applications = current_user.applications.order(id: :desc).page(params[:page])
|
@applications = current_user.applications.order(id: :desc).page(params[:page])
|
||||||
|
@ -70,8 +69,4 @@ class Settings::ApplicationsController < ApplicationController
|
||||||
scopes = params.fetch(:doorkeeper_application, {}).fetch(:scopes, nil)
|
scopes = params.fetch(:doorkeeper_application, {}).fetch(:scopes, nil)
|
||||||
params[:doorkeeper_application][:scopes] = scopes.join(' ') if scopes.is_a? Array
|
params[:doorkeeper_application][:scopes] = scopes.join(' ') if scopes.is_a? Array
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,6 @@ class Settings::DeletesController < ApplicationController
|
||||||
|
|
||||||
before_action :check_enabled_deletion
|
before_action :check_enabled_deletion
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@confirmation = Form::DeleteConfirmation.new
|
@confirmation = Form::DeleteConfirmation.new
|
||||||
|
@ -30,8 +29,4 @@ class Settings::DeletesController < ApplicationController
|
||||||
def delete_params
|
def delete_params
|
||||||
params.require(:form_delete_confirmation).permit(:password)
|
params.require(:form_delete_confirmation).permit(:password)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,6 @@ class Settings::ExportsController < ApplicationController
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@export = Export.new(current_account)
|
@export = Export.new(current_account)
|
||||||
|
@ -21,10 +20,4 @@ class Settings::ExportsController < ApplicationController
|
||||||
|
|
||||||
redirect_to settings_export_path
|
redirect_to settings_export_path
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ class Settings::FollowerDomainsController < ApplicationController
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@account = current_account
|
@account = current_account
|
||||||
|
@ -26,8 +25,4 @@ class Settings::FollowerDomainsController < ApplicationController
|
||||||
def bulk_params
|
def bulk_params
|
||||||
params.permit(select: [])
|
params.permit(select: [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,6 @@ class Settings::ImportsController < ApplicationController
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@import = Import.new
|
@import = Import.new
|
||||||
|
@ -32,8 +31,4 @@ class Settings::ImportsController < ApplicationController
|
||||||
def import_params
|
def import_params
|
||||||
params.require(:import).permit(:data, :type)
|
params.require(:import).permit(:data, :type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ class Settings::MigrationsController < ApplicationController
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@migration = Form::Migration.new(account: current_account.moved_to_account)
|
@migration = Form::Migration.new(account: current_account.moved_to_account)
|
||||||
|
@ -32,8 +31,4 @@ class Settings::MigrationsController < ApplicationController
|
||||||
current_account.moved_to_account_id != @migration.account&.id &&
|
current_account.moved_to_account_id != @migration.account&.id &&
|
||||||
current_account.id != @migration.account&.id
|
current_account.id != @migration.account&.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ class Settings::NotificationsController < ApplicationController
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
|
@ -26,12 +25,8 @@ class Settings::NotificationsController < ApplicationController
|
||||||
|
|
||||||
def user_settings_params
|
def user_settings_params
|
||||||
params.require(:user).permit(
|
params.require(:user).permit(
|
||||||
notification_emails: %i(follow follow_request reblog favourite mention digest report),
|
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
||||||
interactions: %i(must_be_follower must_be_following must_be_following_dm)
|
interactions: %i(must_be_follower must_be_following must_be_following_dm)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ class Settings::PreferencesController < ApplicationController
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
|
@ -41,19 +40,14 @@ class Settings::PreferencesController < ApplicationController
|
||||||
:setting_boost_modal,
|
:setting_boost_modal,
|
||||||
:setting_delete_modal,
|
:setting_delete_modal,
|
||||||
:setting_auto_play_gif,
|
:setting_auto_play_gif,
|
||||||
:setting_display_media,
|
:setting_display_sensitive_media,
|
||||||
:setting_expand_spoilers,
|
|
||||||
:setting_reduce_motion,
|
:setting_reduce_motion,
|
||||||
:setting_system_font_ui,
|
:setting_system_font_ui,
|
||||||
:setting_noindex,
|
:setting_noindex,
|
||||||
:setting_theme,
|
:setting_theme,
|
||||||
:setting_hide_network,
|
:setting_hide_network,
|
||||||
notification_emails: %i(follow follow_request reblog favourite mention digest report),
|
notification_emails: %i(follow follow_request reblog favourite mention digest),
|
||||||
interactions: %i(must_be_follower must_be_following)
|
interactions: %i(must_be_follower must_be_following)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,6 @@ class Settings::ProfilesController < ApplicationController
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
obfuscate_filename [:account, :avatar]
|
obfuscate_filename [:account, :avatar]
|
||||||
obfuscate_filename [:account, :header]
|
obfuscate_filename [:account, :header]
|
||||||
|
@ -35,8 +34,4 @@ class Settings::ProfilesController < ApplicationController
|
||||||
def set_account
|
def set_account
|
||||||
@account = current_user.account
|
@account = current_user.account
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
class Settings::SessionsController < ApplicationController
|
class Settings::SessionsController < ApplicationController
|
||||||
before_action :set_session, only: :destroy
|
before_action :set_session, only: :destroy
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@session.destroy!
|
@session.destroy!
|
||||||
|
@ -15,8 +14,4 @@ class Settings::SessionsController < ApplicationController
|
||||||
def set_session
|
def set_session
|
||||||
@session = current_user.session_activations.find(params[:id])
|
@session = current_user.session_activations.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,6 @@ module Settings
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :ensure_otp_secret
|
before_action :ensure_otp_secret
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
prepare_two_factor_form
|
prepare_two_factor_form
|
||||||
|
@ -44,10 +43,6 @@ module Settings
|
||||||
def ensure_otp_secret
|
def ensure_otp_secret
|
||||||
redirect_to settings_two_factor_authentication_path unless current_user.otp_secret
|
redirect_to settings_two_factor_authentication_path unless current_user.otp_secret
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,6 @@ module Settings
|
||||||
layout 'admin'
|
layout 'admin'
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@recovery_codes = current_user.generate_otp_backup_codes!
|
@recovery_codes = current_user.generate_otp_backup_codes!
|
||||||
|
@ -14,12 +13,6 @@ module Settings
|
||||||
flash[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated')
|
flash[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated')
|
||||||
render :index
|
render :index
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,6 @@ module Settings
|
||||||
|
|
||||||
before_action :authenticate_user!
|
before_action :authenticate_user!
|
||||||
before_action :verify_otp_required, only: [:create]
|
before_action :verify_otp_required, only: [:create]
|
||||||
before_action :set_body_classes
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@confirmation = Form::TwoFactorConfirmation.new
|
@confirmation = Form::TwoFactorConfirmation.new
|
||||||
|
@ -44,9 +43,5 @@ module Settings
|
||||||
current_user.validate_and_consume_otp!(confirmation_params[:code]) ||
|
current_user.validate_and_consume_otp!(confirmation_params[:code]) ||
|
||||||
current_user.invalidate_otp_backup_code!(confirmation_params[:code])
|
current_user.invalidate_otp_backup_code!(confirmation_params[:code])
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_body_classes
|
|
||||||
@body_classes = 'admin'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,22 +12,15 @@ class StatusesController < ApplicationController
|
||||||
|
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :set_status
|
before_action :set_status
|
||||||
before_action :set_instance_presenter
|
|
||||||
before_action :set_link_headers
|
before_action :set_link_headers
|
||||||
before_action :check_account_suspension
|
before_action :check_account_suspension
|
||||||
before_action :redirect_to_original, only: [:show]
|
before_action :redirect_to_original, only: [:show]
|
||||||
before_action :set_referrer_policy_header, only: [:show]
|
before_action :set_referrer_policy_header, only: [:show]
|
||||||
before_action :set_cache_headers
|
before_action :set_cache_headers
|
||||||
|
|
||||||
content_security_policy only: :embed do |p|
|
|
||||||
p.frame_ancestors(false)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
@body_classes = 'with-modals'
|
|
||||||
|
|
||||||
set_ancestors
|
set_ancestors
|
||||||
set_descendants
|
set_descendants
|
||||||
|
|
||||||
|
@ -37,7 +30,7 @@ class StatusesController < ApplicationController
|
||||||
format.json do
|
format.json do
|
||||||
skip_session! unless @stream_entry.hidden?
|
skip_session! unless @stream_entry.hidden?
|
||||||
|
|
||||||
render_cached_json(['activitypub', 'note', @status], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
render_cached_json(['activitypub', 'note', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
||||||
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter)
|
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -47,7 +40,7 @@ class StatusesController < ApplicationController
|
||||||
def activity
|
def activity
|
||||||
skip_session!
|
skip_session!
|
||||||
|
|
||||||
render_cached_json(['activitypub', 'activity', @status], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
render_cached_json(['activitypub', 'activity', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
||||||
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter)
|
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -58,7 +51,6 @@ class StatusesController < ApplicationController
|
||||||
skip_session!
|
skip_session!
|
||||||
expires_in 180, public: true
|
expires_in 180, public: true
|
||||||
response.headers['X-Frame-Options'] = 'ALLOWALL'
|
response.headers['X-Frame-Options'] = 'ALLOWALL'
|
||||||
@autoplay = ActiveModel::Type::Boolean.new.cast(params[:autoplay])
|
|
||||||
|
|
||||||
render 'stream_entries/embed', layout: 'embedded'
|
render 'stream_entries/embed', layout: 'embedded'
|
||||||
end
|
end
|
||||||
|
@ -156,10 +148,6 @@ class StatusesController < ApplicationController
|
||||||
raise ActiveRecord::RecordNotFound
|
raise ActiveRecord::RecordNotFound
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_instance_presenter
|
|
||||||
@instance_presenter = InstancePresenter.new
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_account_suspension
|
def check_account_suspension
|
||||||
gone if @account.suspended?
|
gone if @account.suspended?
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,7 +37,7 @@ class TagsController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_body_classes
|
def set_body_classes
|
||||||
@body_classes = 'with-modals'
|
@body_classes = 'tag-body'
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_instance_presenter
|
def set_instance_presenter
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
module Admin::AccountModerationNotesHelper
|
module Admin::AccountModerationNotesHelper
|
||||||
def admin_account_link_to(account)
|
def admin_account_link_to(account)
|
||||||
return if account.nil?
|
link_to admin_account_path(account.id), class: name_tag_classes(account) do
|
||||||
|
|
||||||
link_to admin_account_path(account.id), class: name_tag_classes(account), title: account.acct do
|
|
||||||
safe_join([
|
safe_join([
|
||||||
image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'),
|
image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'),
|
||||||
content_tag(:span, account.acct, class: 'username'),
|
content_tag(:span, account.acct, class: 'username'),
|
||||||
|
@ -13,9 +11,7 @@ module Admin::AccountModerationNotesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def admin_account_inline_link_to(account)
|
def admin_account_inline_link_to(account)
|
||||||
return if account.nil?
|
link_to admin_account_path(account.id), class: name_tag_classes(account, true) do
|
||||||
|
|
||||||
link_to admin_account_path(account.id), class: name_tag_classes(account, true), title: account.acct do
|
|
||||||
content_tag(:span, account.acct, class: 'username')
|
content_tag(:span, account.acct, class: 'username')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -33,12 +33,8 @@ module Admin::ActionLogsHelper
|
||||||
when 'DomainBlock', 'EmailDomainBlock'
|
when 'DomainBlock', 'EmailDomainBlock'
|
||||||
link_to attributes['domain'], "https://#{attributes['domain']}"
|
link_to attributes['domain'], "https://#{attributes['domain']}"
|
||||||
when 'Status'
|
when 'Status'
|
||||||
tmp_status = Status.new(attributes.except('reblogs_count', 'favourites_count'))
|
tmp_status = Status.new(attributes)
|
||||||
if tmp_status.account
|
link_to tmp_status.account&.acct || "##{tmp_status.account_id}", TagManager.instance.url_for(tmp_status)
|
||||||
link_to tmp_status.account&.acct || "##{tmp_status.account_id}", admin_account_path(tmp_status.account_id)
|
|
||||||
else
|
|
||||||
I18n.t('admin.action_logs.deleted_status')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Admin::FilterHelper
|
module Admin::FilterHelper
|
||||||
ACCOUNT_FILTERS = %i(local remote by_domain silenced suspended alphabetic username display_name email ip staff).freeze
|
ACCOUNT_FILTERS = %i(local remote by_domain silenced suspended recent username display_name email ip staff).freeze
|
||||||
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
|
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
|
||||||
INVITE_FILTER = %i(available expired).freeze
|
INVITE_FILTER = %i(available expired).freeze
|
||||||
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
|
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
|
||||||
|
|
|
@ -7,8 +7,8 @@ module ApplicationHelper
|
||||||
follow
|
follow
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
def active_nav_class(*paths)
|
def active_nav_class(path)
|
||||||
paths.any? { |path| current_page?(path) } ? 'active' : ''
|
current_page?(path) ? 'active' : ''
|
||||||
end
|
end
|
||||||
|
|
||||||
def active_link_to(label, path, **options)
|
def active_link_to(label, path, **options)
|
||||||
|
@ -27,6 +27,11 @@ module ApplicationHelper
|
||||||
Setting.open_deletion
|
Setting.open_deletion
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_rtl_body_class(other_classes)
|
||||||
|
other_classes = "#{other_classes} rtl" if locale_direction == 'rtl'
|
||||||
|
other_classes
|
||||||
|
end
|
||||||
|
|
||||||
def locale_direction
|
def locale_direction
|
||||||
if [:ar, :fa, :he].include?(I18n.locale)
|
if [:ar, :fa, :he].include?(I18n.locale)
|
||||||
'rtl'
|
'rtl'
|
||||||
|
@ -72,29 +77,4 @@ module ApplicationHelper
|
||||||
def react_component(name, props = {})
|
def react_component(name, props = {})
|
||||||
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
|
content_tag(:div, nil, data: { component: name.to_s.camelcase, props: Oj.dump(props) })
|
||||||
end
|
end
|
||||||
|
|
||||||
def body_classes
|
|
||||||
output = (@body_classes || '').split(' ')
|
|
||||||
output << "theme-#{current_theme.parameterize}"
|
|
||||||
output << 'system-font' if current_account&.user&.setting_system_font_ui
|
|
||||||
output << (current_account&.user&.setting_reduce_motion ? 'reduce-motion' : 'no-reduce-motion')
|
|
||||||
output << 'rtl' if locale_direction == 'rtl'
|
|
||||||
output.reject(&:blank?).join(' ')
|
|
||||||
end
|
|
||||||
|
|
||||||
def cdn_host
|
|
||||||
Rails.configuration.action_controller.asset_host
|
|
||||||
end
|
|
||||||
|
|
||||||
def cdn_host?
|
|
||||||
cdn_host.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def storage_host
|
|
||||||
"https://#{ENV['S3_ALIAS_HOST'].presence || ENV['S3_CLOUDFRONT_HOST']}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def storage_host?
|
|
||||||
ENV['S3_ALIAS_HOST'].present? || ENV['S3_CLOUDFRONT_HOST'].present?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,54 +6,4 @@ module HomeHelper
|
||||||
locale: I18n.locale,
|
locale: I18n.locale,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_link_to(account, button = '', size: 36, path: nil)
|
|
||||||
content_tag(:div, class: 'account') do
|
|
||||||
content_tag(:div, class: 'account__wrapper') do
|
|
||||||
section = if account.nil?
|
|
||||||
content_tag(:div, class: 'account__display-name') do
|
|
||||||
content_tag(:div, class: 'account__avatar-wrapper') do
|
|
||||||
content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)})")
|
|
||||||
end +
|
|
||||||
content_tag(:span, class: 'display-name') do
|
|
||||||
content_tag(:strong, t('about.contact_missing')) +
|
|
||||||
content_tag(:span, t('about.contact_unavailable'), class: 'display-name__account')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
link_to(path || TagManager.instance.url_for(account), class: 'account__display-name') do
|
|
||||||
content_tag(:div, class: 'account__avatar-wrapper') do
|
|
||||||
content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{account.avatar.url})")
|
|
||||||
end +
|
|
||||||
content_tag(:span, class: 'display-name') do
|
|
||||||
content_tag(:bdi) do
|
|
||||||
content_tag(:strong, display_name(account, custom_emojify: true), class: 'display-name__html emojify')
|
|
||||||
end +
|
|
||||||
content_tag(:span, "@#{account.acct}", class: 'display-name__account')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
section + button
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def obscured_counter(count)
|
|
||||||
if count <= 0
|
|
||||||
0
|
|
||||||
elsif count == 1
|
|
||||||
1
|
|
||||||
else
|
|
||||||
'1+'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def custom_field_classes(field)
|
|
||||||
if field.verified?
|
|
||||||
'verified'
|
|
||||||
else
|
|
||||||
'emojify'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,12 +5,9 @@ module SettingsHelper
|
||||||
en: 'English',
|
en: 'English',
|
||||||
'en-CY': 'English (Cybre)',
|
'en-CY': 'English (Cybre)',
|
||||||
ar: 'العربية',
|
ar: 'العربية',
|
||||||
ast: 'l\'asturianu',
|
|
||||||
bg: 'Български',
|
bg: 'Български',
|
||||||
ca: 'Català',
|
ca: 'Català',
|
||||||
co: 'Corsu',
|
co: 'Corsu',
|
||||||
cs: 'Čeština',
|
|
||||||
cy: 'Cymraeg',
|
|
||||||
da: 'Dansk',
|
da: 'Dansk',
|
||||||
de: 'Deutsch',
|
de: 'Deutsch',
|
||||||
el: 'Ελληνικά',
|
el: 'Ελληνικά',
|
||||||
|
@ -29,7 +26,6 @@ module SettingsHelper
|
||||||
io: 'Ido',
|
io: 'Ido',
|
||||||
it: 'Italiano',
|
it: 'Italiano',
|
||||||
ja: '日本語',
|
ja: '日本語',
|
||||||
ka: 'ქართული',
|
|
||||||
ko: '한국어',
|
ko: '한국어',
|
||||||
nl: 'Nederlands',
|
nl: 'Nederlands',
|
||||||
no: 'Norsk',
|
no: 'Norsk',
|
||||||
|
@ -37,14 +33,12 @@ module SettingsHelper
|
||||||
pl: 'Polszczyzna',
|
pl: 'Polszczyzna',
|
||||||
pt: 'Português',
|
pt: 'Português',
|
||||||
'pt-BR': 'Português do Brasil',
|
'pt-BR': 'Português do Brasil',
|
||||||
ro: 'Limba română',
|
|
||||||
ru: 'Русский',
|
ru: 'Русский',
|
||||||
sk: 'Slovenčina',
|
sk: 'Slovensky',
|
||||||
sl: 'Slovenščina',
|
sl: 'Slovenščina',
|
||||||
sr: 'Српски',
|
sr: 'Српски',
|
||||||
'sr-Latn': 'Srpski (latinica)',
|
'sr-Latn': 'Srpski (latinica)',
|
||||||
sv: 'Svenska',
|
sv: 'Svenska',
|
||||||
ta: 'தமிழ்',
|
|
||||||
te: 'తెలుగు',
|
te: 'తెలుగు',
|
||||||
th: 'ภาษาไทย',
|
th: 'ภาษาไทย',
|
||||||
tr: 'Türkçe',
|
tr: 'Türkçe',
|
||||||
|
|
|
@ -12,67 +12,21 @@ module StreamEntriesHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_action_button(account)
|
|
||||||
if user_signed_in?
|
|
||||||
if account.id == current_user.account_id
|
|
||||||
link_to settings_profile_url, class: 'button logo-button' do
|
|
||||||
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('settings.edit_profile')])
|
|
||||||
end
|
|
||||||
elsif current_account.following?(account) || current_account.requested?(account)
|
|
||||||
link_to account_unfollow_path(account), class: 'button logo-button button--destructive', data: { method: :post } do
|
|
||||||
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.unfollow')])
|
|
||||||
end
|
|
||||||
elsif !(account.memorial? || account.moved?)
|
|
||||||
link_to account_follow_path(account), class: 'button logo-button', data: { method: :post } do
|
|
||||||
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elsif !(account.memorial? || account.moved?)
|
|
||||||
link_to account_remote_follow_path(account), class: 'button logo-button modal-button', target: '_new' do
|
|
||||||
safe_join([render(file: Rails.root.join('app', 'javascript', 'images', 'logo.svg')), t('accounts.follow')])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_badge(account)
|
|
||||||
if account.bot?
|
|
||||||
content_tag(:div, content_tag(:div, t('accounts.roles.bot'), class: 'account-role bot'), class: 'roles')
|
|
||||||
elsif Setting.show_staff_badge && account.user_staff?
|
|
||||||
content_tag(:div, class: 'roles') do
|
|
||||||
if account.user_admin?
|
|
||||||
content_tag(:div, t('accounts.roles.admin'), class: 'account-role admin')
|
|
||||||
elsif account.user_moderator?
|
|
||||||
content_tag(:div, t('accounts.roles.moderator'), class: 'account-role moderator')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_to_more(url)
|
|
||||||
link_to t('statuses.show_more'), url, class: 'load-more load-gap'
|
|
||||||
end
|
|
||||||
|
|
||||||
def nothing_here(extra_classes = '')
|
|
||||||
content_tag(:div, class: "nothing-here #{extra_classes}") do
|
|
||||||
t('accounts.nothing_here')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_description(account)
|
def account_description(account)
|
||||||
prepend_str = [
|
prepend_str = [
|
||||||
[
|
[
|
||||||
number_to_human(account.statuses_count, strip_insignificant_zeros: true),
|
number_to_human(account.statuses_count, strip_insignificant_zeros: true),
|
||||||
I18n.t('accounts.posts', count: account.statuses_count),
|
I18n.t('accounts.posts'),
|
||||||
].join(' '),
|
].join(' '),
|
||||||
|
|
||||||
[
|
[
|
||||||
number_to_human(account.following_count, strip_insignificant_zeros: true),
|
number_to_human(account.following_count, strip_insignificant_zeros: true),
|
||||||
I18n.t('accounts.following', count: account.following_count),
|
I18n.t('accounts.following'),
|
||||||
].join(' '),
|
].join(' '),
|
||||||
|
|
||||||
[
|
[
|
||||||
number_to_human(account.followers_count, strip_insignificant_zeros: true),
|
number_to_human(account.followers_count, strip_insignificant_zeros: true),
|
||||||
I18n.t('accounts.followers', count: account.followers_count),
|
I18n.t('accounts.followers'),
|
||||||
].join(' '),
|
].join(' '),
|
||||||
].join(', ')
|
].join(', ')
|
||||||
|
|
||||||
|
@ -113,7 +67,7 @@ module StreamEntriesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def acct(account)
|
def acct(account)
|
||||||
if account.local?
|
if embedded_view? && account.local?
|
||||||
"@#{account.acct}@#{Rails.configuration.x.local_domain}"
|
"@#{account.acct}@#{Rails.configuration.x.local_domain}"
|
||||||
else
|
else
|
||||||
"@#{account.acct}"
|
"@#{account.acct}"
|
||||||
|
|
Before Width: | Height: | Size: 423 B After Width: | Height: | Size: 582 B |
Before Width: | Height: | Size: 253 B After Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 520 B |
Before Width: | Height: | Size: 225 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 412 B After Width: | Height: | Size: 541 B |
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 550 B |