forked from AkkomaGang/akkoma
Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into feature/jobs
# Conflicts: # lib/pleroma/web/federator/federator.ex # lib/pleroma/web/websub/websub.ex
This commit is contained in:
commit
305d219413
481 changed files with 995 additions and 341 deletions
|
@ -57,7 +57,7 @@
|
||||||
|
|
||||||
# For some checks, like AliasUsage, you can only customize the priority
|
# For some checks, like AliasUsage, you can only customize the priority
|
||||||
# Priority values are: `low, normal, high, higher`
|
# Priority values are: `low, normal, high, higher`
|
||||||
{Credo.Check.Design.AliasUsage, priority: :low},
|
{Credo.Check.Design.AliasUsage, priority: :low, if_called_more_often_than: 3},
|
||||||
|
|
||||||
# For others you can set parameters
|
# For others you can set parameters
|
||||||
|
|
||||||
|
@ -104,7 +104,8 @@
|
||||||
{Credo.Check.Warning.BoolOperationOnSameValues},
|
{Credo.Check.Warning.BoolOperationOnSameValues},
|
||||||
{Credo.Check.Warning.IExPry},
|
{Credo.Check.Warning.IExPry},
|
||||||
{Credo.Check.Warning.IoInspect},
|
{Credo.Check.Warning.IoInspect},
|
||||||
{Credo.Check.Warning.LazyLogging},
|
# Got too much of them, not sure if relevant
|
||||||
|
{Credo.Check.Warning.LazyLogging, false},
|
||||||
{Credo.Check.Warning.OperationOnSameValues},
|
{Credo.Check.Warning.OperationOnSameValues},
|
||||||
{Credo.Check.Warning.OperationWithConstantResult},
|
{Credo.Check.Warning.OperationWithConstantResult},
|
||||||
{Credo.Check.Warning.UnusedEnumOperation},
|
{Credo.Check.Warning.UnusedEnumOperation},
|
||||||
|
|
15
README.md
15
README.md
|
@ -8,20 +8,7 @@ Pleroma is written in Elixir, high-performance and can run on small devices like
|
||||||
|
|
||||||
For clients it supports both the [GNU Social API with Qvitter extensions](https://twitter-api.readthedocs.io/en/latest/index.html) and the [Mastodon client API](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md).
|
For clients it supports both the [GNU Social API with Qvitter extensions](https://twitter-api.readthedocs.io/en/latest/index.html) and the [Mastodon client API](https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md).
|
||||||
|
|
||||||
Client applications that are committed to supporting Pleroma:
|
- [Client Applications for Pleroma](docs/Clients.md)
|
||||||
|
|
||||||
* Mastalab (Android)
|
|
||||||
* Tusky (Android)
|
|
||||||
* Twidere (Android)
|
|
||||||
* Mast (iOS)
|
|
||||||
* Amaroq (iOS)
|
|
||||||
|
|
||||||
Client applications that are known to work well:
|
|
||||||
|
|
||||||
* Pawoo (Android + iOS)
|
|
||||||
* Tootdon (Android + iOS)
|
|
||||||
* Tootle (iOS)
|
|
||||||
* Whalebird (Windows + Mac + Linux)
|
|
||||||
|
|
||||||
No release has been made yet, but several servers have been online for months already. If you want to run your own server, feel free to contact us at @lain@pleroma.soykaf.com or in our dev chat at #pleroma on freenode or via matrix at <https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org>.
|
No release has been made yet, but several servers have been online for months already. If you want to run your own server, feel free to contact us at @lain@pleroma.soykaf.com or in our dev chat at #pleroma on freenode or via matrix at <https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org>.
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@
|
||||||
config :logger, :ex_syslogger,
|
config :logger, :ex_syslogger,
|
||||||
level: :debug,
|
level: :debug,
|
||||||
ident: "Pleroma",
|
ident: "Pleroma",
|
||||||
format: "$date $time $metadata[$level] $message",
|
format: "$metadata[$level] $message",
|
||||||
metadata: [:request_id]
|
metadata: [:request_id]
|
||||||
|
|
||||||
config :mime, :types, %{
|
config :mime, :types, %{
|
||||||
|
@ -238,6 +238,11 @@
|
||||||
reject: [],
|
reject: [],
|
||||||
accept: []
|
accept: []
|
||||||
|
|
||||||
|
config :pleroma, :mrf_keyword,
|
||||||
|
reject: [],
|
||||||
|
federated_timeline_removal: [],
|
||||||
|
replace: []
|
||||||
|
|
||||||
config :pleroma, :rich_media, enabled: true
|
config :pleroma, :rich_media, enabled: true
|
||||||
|
|
||||||
config :pleroma, :media_proxy,
|
config :pleroma, :media_proxy,
|
||||||
|
|
87
docs/Clients.md
Normal file
87
docs/Clients.md
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
# Pleroma Clients
|
||||||
|
Note: Additionnal clients may be working but theses are officially supporting Pleroma.
|
||||||
|
Feel free to contact us to be added to this list!
|
||||||
|
|
||||||
|
## Desktop
|
||||||
|
### Roma for Desktop
|
||||||
|
- Homepage: <http://www.pleroma.com/desktop-app/>
|
||||||
|
- Source Code: ???
|
||||||
|
- Platforms: Windows, Mac, (Linux?)
|
||||||
|
|
||||||
|
### Social
|
||||||
|
- Source Code: <https://gitlab.gnome.org/BrainBlasted/Social>
|
||||||
|
- Contact: [@brainblasted@social.libre.fi](https://social.libre.fi/users/brainblasted)
|
||||||
|
- Platforms: Linux (GNOME)
|
||||||
|
- Note(2019-01-28): Not at a pre-alpha stage yet
|
||||||
|
|
||||||
|
### Whalebird
|
||||||
|
- Homepage: <https://whalebird.org/>
|
||||||
|
- Source Code: <https://github.com/h3poteto/whalebird-desktop>
|
||||||
|
- Contact: [@h3poteto@pleroma.io](https://pleroma.io/users/h3poteto)
|
||||||
|
- Platforms: Windows, Mac, Linux
|
||||||
|
|
||||||
|
## Handheld
|
||||||
|
### Amaroq
|
||||||
|
- Homepage: <https://itunes.apple.com/us/app/amaroq-for-mastodon/id1214116200>
|
||||||
|
- Source Code: <https://github.com/ReticentJohn/Amaroq>
|
||||||
|
- Contact: [@eurasierboy@mastodon.social](https://mastodon.social/users/eurasierboy)
|
||||||
|
- Platforms: iOS
|
||||||
|
|
||||||
|
### Nekonium
|
||||||
|
- Homepage: [F-Droid Repository](https://repo.gdgd.jp.net/), [Google Play](https://play.google.com/store/apps/details?id=com.apps.nekonium), [Amazon](https://www.amazon.co.jp/dp/B076FXPRBC/)
|
||||||
|
- Source: <https://git.gdgd.jp.net/lin/nekonium/>
|
||||||
|
- Contact: [@lin@pleroma.gdgd.jp.net](https://pleroma.gdgd.jp.net/users/lin)
|
||||||
|
- Platforms: Android
|
||||||
|
|
||||||
|
### Mastalab
|
||||||
|
- Source Code: <https://gitlab.com/tom79/mastalab/>
|
||||||
|
- Contact: [@tom79@mastodon.social](https://mastodon.social/users/tom79)
|
||||||
|
- Platforms: Android
|
||||||
|
|
||||||
|
### Roma
|
||||||
|
- Homepage: <http://www.pleroma.com/>
|
||||||
|
- Source Code: ???
|
||||||
|
- Platforms: iOS, Android
|
||||||
|
|
||||||
|
### Tootdon
|
||||||
|
- Homepage: <http://tootdon.club/>, <http://blog.mastodon-tootdon.com/>
|
||||||
|
- Source Code: ???
|
||||||
|
- Contact: [@tootdon@mstdn.jp](https://mstdn.jp/users/tootdon)
|
||||||
|
- Platforms: Android, iOS
|
||||||
|
|
||||||
|
### Tusky
|
||||||
|
- Homepage: <https://tuskyapp.github.io/>
|
||||||
|
- Source Code: <https://github.com/tuskyapp/Tusky>
|
||||||
|
- Contact: [@ConnyDuck@mastodon.social](https://mastodon.social/users/ConnyDuck)
|
||||||
|
- Platforms: Android
|
||||||
|
|
||||||
|
### Twidere
|
||||||
|
- Homepage: <https://twidere.mariotaku.org/>
|
||||||
|
- Source Code: <https://github.com/TwidereProject/Twidere-Android/>, <https://github.com/TwidereProject/Twidere-iOS/>
|
||||||
|
- Contact: <me@mariotaku.org>
|
||||||
|
- Platform: Android, iOS
|
||||||
|
|
||||||
|
## Alternative Web Interfaces
|
||||||
|
### Brutaldon
|
||||||
|
- Homepage: <https://jfm.carcosa.net/projects/software/brutaldon/>
|
||||||
|
- Source Code: <https://github.com/jfmcbrayer/brutaldon>
|
||||||
|
- Contact: [@gcupc@glitch.social](https://glitch.social/users/gcupc)
|
||||||
|
|
||||||
|
### Feather
|
||||||
|
- Source Code: <https://github.com/kaniini/feather>
|
||||||
|
- Contact: [@kaniini@pleroma.site](https://pleroma.site/kaniini)
|
||||||
|
|
||||||
|
### Halcyon
|
||||||
|
- Source Code: <https://notabug.org/halcyon-suite/halcyon>
|
||||||
|
- Contact: [@halcyon@social.csswg.org](https://social.csswg.org/users/halcyon)
|
||||||
|
|
||||||
|
### Pinafore
|
||||||
|
- Homepage: <https://pinafore.social/>
|
||||||
|
- Source Code: <https://github.com/nolanlawson/pinafore>
|
||||||
|
- Contact: [@pinafore@mastodon.technology](https://mastodon.technology/users/pinafore)
|
||||||
|
- Note: Pleroma support is a secondary goal
|
||||||
|
|
||||||
|
### Sengi
|
||||||
|
- Source Code: <https://github.com/NicolasConstant/sengi>
|
||||||
|
- Contact: [@sengi_app@mastodon.social](https://mastodon.social/users/sengi_app)
|
||||||
|
- Note(2019-01-28): The development is currently in a early stage.
|
|
@ -101,6 +101,26 @@ config :pleroma, Pleroma.Mailer,
|
||||||
|
|
||||||
## :logger
|
## :logger
|
||||||
* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog
|
* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog
|
||||||
|
|
||||||
|
An example to enable ONLY ExSyslogger (f/ex in ``prod.secret.exs``) with info and debug suppressed:
|
||||||
|
```
|
||||||
|
config :logger,
|
||||||
|
backends: [{ExSyslogger, :ex_syslogger}]
|
||||||
|
|
||||||
|
config :logger, :ex_syslogger,
|
||||||
|
level: :warn
|
||||||
|
```
|
||||||
|
|
||||||
|
Another example, keeping console output and adding the pid to syslog output:
|
||||||
|
```
|
||||||
|
config :logger,
|
||||||
|
backends: [:console, {ExSyslogger, :ex_syslogger}]
|
||||||
|
|
||||||
|
config :logger, :ex_syslogger,
|
||||||
|
level: :warn,
|
||||||
|
option: [:pid, :ndelay]
|
||||||
|
```
|
||||||
|
|
||||||
See: [logger’s documentation](https://hexdocs.pm/logger/Logger.html) and [ex_syslogger’s documentation](https://hexdocs.pm/ex_syslogger/)
|
See: [logger’s documentation](https://hexdocs.pm/logger/Logger.html) and [ex_syslogger’s documentation](https://hexdocs.pm/ex_syslogger/)
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,6 +172,11 @@ This section is used to configure Pleroma-FE, unless ``:managed_config`` in ``:i
|
||||||
* `delist_threshold`: Number of mentioned users after which the message gets delisted (the message can still be seen, but it will not show up in public timelines and mentioned users won't get notifications about it). Set to 0 to disable.
|
* `delist_threshold`: Number of mentioned users after which the message gets delisted (the message can still be seen, but it will not show up in public timelines and mentioned users won't get notifications about it). Set to 0 to disable.
|
||||||
* `reject_threshold`: Number of mentioned users after which the messaged gets rejected. Set to 0 to disable.
|
* `reject_threshold`: Number of mentioned users after which the messaged gets rejected. Set to 0 to disable.
|
||||||
|
|
||||||
|
## :mrf_keyword
|
||||||
|
* `reject`: A list of patterns which result in message being rejected, each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html)
|
||||||
|
* `federated_timeline_removal`: A list of patterns which result in message being removed from federated timelines (a.k.a unlisted), each pattern can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html)
|
||||||
|
* `replace`: A list of tuples containing `{pattern, replacement}`, `pattern` can be a string or a [regular expression](https://hexdocs.pm/elixir/Regex.html)
|
||||||
|
|
||||||
## :media_proxy
|
## :media_proxy
|
||||||
* `enabled`: Enables proxying of remote media to the instance’s proxy
|
* `enabled`: Enables proxying of remote media to the instance’s proxy
|
||||||
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.
|
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.
|
||||||
|
|
|
@ -23,6 +23,11 @@ example.tld {
|
||||||
|
|
||||||
# If you do not want to use the mediaproxy function, remove these lines.
|
# If you do not want to use the mediaproxy function, remove these lines.
|
||||||
# To use this directive, you need the http.cache plugin for Caddy.
|
# To use this directive, you need the http.cache plugin for Caddy.
|
||||||
|
cache {
|
||||||
|
match_path /media
|
||||||
|
default_max_age 720m
|
||||||
|
}
|
||||||
|
|
||||||
cache {
|
cache {
|
||||||
match_path /proxy
|
match_path /proxy
|
||||||
default_max_age 720m
|
default_max_age 720m
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/sbin/openrc-run
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
# Requires OpenRC >= 0.35
|
# Requires OpenRC >= 0.35
|
||||||
directory=~pleroma/pleroma
|
directory=/opt/pleroma
|
||||||
|
|
||||||
command=/usr/bin/mix
|
command=/usr/bin/mix
|
||||||
command_args="phx.server"
|
command_args="phx.server"
|
||||||
|
|
|
@ -15,12 +15,13 @@ server {
|
||||||
return 301 https://$server_name$request_uri;
|
return 301 https://$server_name$request_uri;
|
||||||
|
|
||||||
# Uncomment this if you need to use the 'webroot' method with certbot. Make sure
|
# Uncomment this if you need to use the 'webroot' method with certbot. Make sure
|
||||||
# that you also create the .well-known/acme-challenge directory structure in pleroma/priv/static and
|
# that the directory exists and that it is accessible by the webserver. If you followed
|
||||||
# that is is accessible by the webserver. You may need to load this file with the ssl
|
# the guide, you already ran 'sudo mkdir -p /var/lib/letsencrypt' to create the folder.
|
||||||
# server block commented out, run certbot to get the certificate, and then uncomment it.
|
# You may need to load this file with the ssl server block commented out, run certbot
|
||||||
|
# to get the certificate, and then uncomment it.
|
||||||
#
|
#
|
||||||
# location ~ /\.well-known/acme-challenge {
|
# location ~ /\.well-known/acme-challenge {
|
||||||
# root <path to install>/pleroma/priv/static/;
|
# root /var/lib/letsencrypt/.well-known/acme-challenge;
|
||||||
# }
|
# }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,17 @@ Environment="MIX_ENV=prod"
|
||||||
|
|
||||||
; Make sure that all paths fit your installation.
|
; Make sure that all paths fit your installation.
|
||||||
; Path to the home directory of the user running the Pleroma service.
|
; Path to the home directory of the user running the Pleroma service.
|
||||||
Environment="HOME=/home/pleroma"
|
Environment="HOME=/var/lib/pleroma"
|
||||||
; Path to the folder containing the Pleroma installation.
|
; Path to the folder containing the Pleroma installation.
|
||||||
WorkingDirectory=/home/pleroma/pleroma
|
WorkingDirectory=/opt/pleroma
|
||||||
; Path to the Mix binary.
|
; Path to the Mix binary.
|
||||||
ExecStart=/usr/bin/mix phx.server
|
ExecStart=/usr/bin/mix phx.server
|
||||||
|
|
||||||
; Some security directives.
|
; Some security directives.
|
||||||
; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops.
|
; Use private /tmp and /var/tmp folders inside a new file system namespace, which are discarded after the process stops.
|
||||||
PrivateTmp=true
|
PrivateTmp=true
|
||||||
|
; The /home, /root, and /run/user folders can not be accessed by this service anymore. If your Pleroma user has its home folder in one of the restricted places, or use one of these folders as its working directory, you have to set this to false.
|
||||||
|
ProtectHome=true
|
||||||
; Mount /usr, /boot, and /etc as read-only for processes invoked by this service.
|
; Mount /usr, /boot, and /etc as read-only for processes invoked by this service.
|
||||||
ProtectSystem=full
|
ProtectSystem=full
|
||||||
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled by default because it may not work on devices like the Raspberry Pi.
|
; Sets up a new /dev mount for the process and only adds API pseudo devices like /dev/null, /dev/zero or /dev/random but not physical devices. Disabled by default because it may not work on devices like the Raspberry Pi.
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
defmodule Mix.Tasks.Pleroma.Uploads do
|
defmodule Mix.Tasks.Pleroma.Uploads do
|
||||||
use Mix.Task
|
use Mix.Task
|
||||||
alias Pleroma.{Upload, Uploaders.Local}
|
alias Pleroma.Upload
|
||||||
|
alias Pleroma.Uploaders.Local
|
||||||
alias Mix.Tasks.Pleroma.Common
|
alias Mix.Tasks.Pleroma.Common
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ defmodule Mix.Tasks.Pleroma.Uploads do
|
||||||
- `--delete` - delete local uploads after migrating them to the target uploader
|
- `--delete` - delete local uploads after migrating them to the target uploader
|
||||||
|
|
||||||
|
|
||||||
A list of avalible uploaders can be seen in config.exs
|
A list of available uploaders can be seen in config.exs
|
||||||
"""
|
"""
|
||||||
def run(["migrate_local", target_uploader | args]) do
|
def run(["migrate_local", target_uploader | args]) do
|
||||||
delete? = Enum.member?(args, "--delete")
|
delete? = Enum.member?(args, "--delete")
|
||||||
|
@ -96,6 +97,7 @@ def run(["migrate_local", target_uploader | args]) do
|
||||||
timeout: 150_000
|
timeout: 150_000
|
||||||
)
|
)
|
||||||
|> Stream.chunk_every(@log_every)
|
|> Stream.chunk_every(@log_every)
|
||||||
|
# credo:disable-for-next-line Credo.Check.Warning.UnusedEnumOperation
|
||||||
|> Enum.reduce(0, fn done, count ->
|
|> Enum.reduce(0, fn done, count ->
|
||||||
count = count + length(done)
|
count = count + length(done)
|
||||||
Mix.shell().info("Uploaded #{count}/#{total_count} files")
|
Mix.shell().info("Uploaded #{count}/#{total_count} files")
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
defmodule Mix.Tasks.Pleroma.User do
|
defmodule Mix.Tasks.Pleroma.User do
|
||||||
use Mix.Task
|
use Mix.Task
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
alias Pleroma.{Repo, User}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
alias Mix.Tasks.Pleroma.Common
|
alias Mix.Tasks.Pleroma.Common
|
||||||
|
|
||||||
@shortdoc "Manages Pleroma users"
|
@shortdoc "Manages Pleroma users"
|
||||||
|
@ -211,7 +212,7 @@ def run(["unsubscribe", nickname]) do
|
||||||
|
|
||||||
user = Repo.get(User, user.id)
|
user = Repo.get(User, user.id)
|
||||||
|
|
||||||
if length(user.following) == 0 do
|
if Enum.empty?(user.following) do
|
||||||
Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}")
|
Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
@ -7,7 +7,9 @@ defmodule Pleroma.PasswordResetToken do
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
alias Pleroma.{User, PasswordResetToken, Repo}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.PasswordResetToken
|
||||||
|
|
||||||
schema "password_reset_tokens" do
|
schema "password_reset_tokens" do
|
||||||
belongs_to(:user, User, type: Pleroma.FlakeId)
|
belongs_to(:user, User, type: Pleroma.FlakeId)
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
|
|
||||||
defmodule Pleroma.Activity do
|
defmodule Pleroma.Activity do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
alias Pleroma.{Repo, Activity, Notification}
|
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Notification
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
@type t :: %__MODULE__{}
|
@type t :: %__MODULE__{}
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Captcha do
|
defmodule Pleroma.Captcha do
|
||||||
|
alias Calendar.DateTime
|
||||||
alias Plug.Crypto.KeyGenerator
|
alias Plug.Crypto.KeyGenerator
|
||||||
alias Plug.Crypto.MessageEncryptor
|
alias Plug.Crypto.MessageEncryptor
|
||||||
alias Calendar.DateTime
|
|
||||||
|
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,8 @@ defmodule Pleroma.UserEmail do
|
||||||
|
|
||||||
import Swoosh.Email
|
import Swoosh.Email
|
||||||
|
|
||||||
alias Pleroma.Web.{Endpoint, Router}
|
alias Pleroma.Web.Endpoint
|
||||||
|
alias Pleroma.Web.Router
|
||||||
|
|
||||||
defp instance_config, do: Pleroma.Config.get(:instance)
|
defp instance_config, do: Pleroma.Config.get(:instance)
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,12 @@
|
||||||
|
|
||||||
defmodule Pleroma.Filter do
|
defmodule Pleroma.Filter do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.{Changeset, Query}
|
|
||||||
alias Pleroma.{User, Repo}
|
import Ecto.Changeset
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
schema "filters" do
|
schema "filters" do
|
||||||
belongs_to(:user, User, type: Pleroma.FlakeId)
|
belongs_to(:user, User, type: Pleroma.FlakeId)
|
||||||
|
|
|
@ -27,7 +27,7 @@ def to_string(<<0::integer-size(64), id::integer-size(64)>>) do
|
||||||
Kernel.to_string(id)
|
Kernel.to_string(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_string(flake = <<_::integer-size(64), _::integer-size(48), _::integer-size(16)>>) do
|
def to_string(<<_::integer-size(64), _::integer-size(48), _::integer-size(16)>> = flake) do
|
||||||
encode_base62(flake)
|
encode_base62(flake)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ def from_string(unquote(i)), do: <<0::integer-size(128)>>
|
||||||
def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>>
|
def from_string(unquote(Kernel.to_string(i))), do: <<0::integer-size(128)>>
|
||||||
end
|
end
|
||||||
|
|
||||||
def from_string(flake = <<_::integer-size(128)>>), do: flake
|
def from_string(<<_::integer-size(128)>> = flake), do: flake
|
||||||
|
|
||||||
def from_string(string) when is_binary(string) and byte_size(string) < 18 do
|
def from_string(string) when is_binary(string) and byte_size(string) < 18 do
|
||||||
case Integer.parse(string) do
|
case Integer.parse(string) do
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Formatter do
|
defmodule Pleroma.Formatter do
|
||||||
|
alias Pleroma.Emoji
|
||||||
|
alias Pleroma.HTML
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
alias Pleroma.HTML
|
|
||||||
alias Pleroma.Emoji
|
|
||||||
|
|
||||||
@tag_regex ~r/((?<=[^&])|\A)(\#)(\w+)/u
|
@tag_regex ~r/((?<=[^&])|\A)(\#)(\w+)/u
|
||||||
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
|
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
|
||||||
|
|
|
@ -37,17 +37,17 @@ def init([ip, port]) do
|
||||||
|
|
||||||
defmodule Pleroma.Gopher.Server.ProtocolHandler do
|
defmodule Pleroma.Gopher.Server.ProtocolHandler do
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Repo
|
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
def start_link(ref, socket, transport, opts) do
|
def start_link(ref, socket, transport, opts) do
|
||||||
pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])
|
pid = spawn_link(__MODULE__, :init, [ref, socket, transport, opts])
|
||||||
{:ok, pid}
|
{:ok, pid}
|
||||||
end
|
end
|
||||||
|
|
||||||
def init(ref, socket, transport, _Opts = []) do
|
def init(ref, socket, transport, [] = _Opts) do
|
||||||
:ok = :ranch.accept_ack(ref)
|
:ok = :ranch.accept_ack(ref)
|
||||||
loop(socket, transport)
|
loop(socket, transport)
|
||||||
end
|
end
|
||||||
|
|
|
@ -83,8 +83,7 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@markup Application.get_env(:pleroma, :markup)
|
@markup Application.get_env(:pleroma, :markup)
|
||||||
@uri_schemes Application.get_env(:pleroma, :uri_schemes, [])
|
@valid_schemes Pleroma.Config.get([:uri_schemes, :valid_schemes], [])
|
||||||
@valid_schemes Keyword.get(@uri_schemes, :valid_schemes, [])
|
|
||||||
|
|
||||||
require HtmlSanitizeEx.Scrubber.Meta
|
require HtmlSanitizeEx.Scrubber.Meta
|
||||||
alias HtmlSanitizeEx.Scrubber.Meta
|
alias HtmlSanitizeEx.Scrubber.Meta
|
||||||
|
@ -126,10 +125,11 @@ defmodule Pleroma.HTML.Scrubber.Default do
|
||||||
|
|
||||||
require HtmlSanitizeEx.Scrubber.Meta
|
require HtmlSanitizeEx.Scrubber.Meta
|
||||||
alias HtmlSanitizeEx.Scrubber.Meta
|
alias HtmlSanitizeEx.Scrubber.Meta
|
||||||
|
# credo:disable-for-previous-line
|
||||||
|
# No idea how to fix this one…
|
||||||
|
|
||||||
@markup Application.get_env(:pleroma, :markup)
|
@markup Application.get_env(:pleroma, :markup)
|
||||||
@uri_schemes Application.get_env(:pleroma, :uri_schemes, [])
|
@valid_schemes Pleroma.Config.get([:uri_schemes, :valid_schemes], [])
|
||||||
@valid_schemes Keyword.get(@uri_schemes, :valid_schemes, [])
|
|
||||||
|
|
||||||
Meta.remove_cdata_sections_before_scrub()
|
Meta.remove_cdata_sections_before_scrub()
|
||||||
Meta.strip_comments()
|
Meta.strip_comments()
|
||||||
|
|
|
@ -2,13 +2,13 @@ defmodule Pleroma.Instances.Instance do
|
||||||
@moduledoc "Instance."
|
@moduledoc "Instance."
|
||||||
|
|
||||||
alias Pleroma.Instances
|
alias Pleroma.Instances
|
||||||
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Instances.Instance
|
alias Pleroma.Instances.Instance
|
||||||
|
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
import Ecto.{Query, Changeset}
|
import Ecto.Query
|
||||||
|
import Ecto.Changeset
|
||||||
alias Pleroma.Repo
|
|
||||||
|
|
||||||
schema "instances" do
|
schema "instances" do
|
||||||
field(:host, :string)
|
field(:host, :string)
|
||||||
|
|
|
@ -4,8 +4,13 @@
|
||||||
|
|
||||||
defmodule Pleroma.List do
|
defmodule Pleroma.List do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.{Changeset, Query}
|
|
||||||
alias Pleroma.{User, Repo, Activity}
|
import Ecto.Query
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
schema "lists" do
|
schema "lists" do
|
||||||
belongs_to(:user, User, type: Pleroma.FlakeId)
|
belongs_to(:user, User, type: Pleroma.FlakeId)
|
||||||
|
|
|
@ -4,8 +4,13 @@
|
||||||
|
|
||||||
defmodule Pleroma.Notification do
|
defmodule Pleroma.Notification do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
alias Pleroma.{User, Activity, Notification, Repo}
|
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Notification
|
||||||
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
schema "notifications" do
|
schema "notifications" do
|
||||||
|
|
|
@ -4,8 +4,15 @@
|
||||||
|
|
||||||
defmodule Pleroma.Object do
|
defmodule Pleroma.Object do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
alias Pleroma.{Repo, Object, User, Activity, ObjectTombstone}
|
|
||||||
import Ecto.{Query, Changeset}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.ObjectTombstone
|
||||||
|
|
||||||
|
import Ecto.Query
|
||||||
|
import Ecto.Changeset
|
||||||
|
|
||||||
schema "objects" do
|
schema "objects" do
|
||||||
field(:data, :map)
|
field(:data, :map)
|
||||||
|
@ -13,9 +20,29 @@ defmodule Pleroma.Object do
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def insert_or_get(cng) do
|
||||||
|
{_, data} = fetch_field(cng, :data)
|
||||||
|
id = data["id"] || data[:id]
|
||||||
|
key = "object:#{id}"
|
||||||
|
|
||||||
|
fetcher = fn _ ->
|
||||||
|
with nil <- get_by_ap_id(id),
|
||||||
|
{:ok, object} <- Repo.insert(cng) do
|
||||||
|
{:commit, object}
|
||||||
|
else
|
||||||
|
%Object{} = object -> {:commit, object}
|
||||||
|
e -> {:ignore, e}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
with {state, object} when state in [:commit, :ok] <- Cachex.fetch(:object_cache, key, fetcher) do
|
||||||
|
{:ok, object}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def create(data) do
|
def create(data) do
|
||||||
Object.change(%Object{}, %{data: data})
|
Object.change(%Object{}, %{data: data})
|
||||||
|> Repo.insert()
|
|> insert_or_get()
|
||||||
end
|
end
|
||||||
|
|
||||||
def change(struct, params \\ %{}) do
|
def change(struct, params \\ %{}) do
|
||||||
|
|
|
@ -33,7 +33,7 @@ def init(opts) do
|
||||||
for only <- @only do
|
for only <- @only do
|
||||||
at = Plug.Router.Utils.split("/")
|
at = Plug.Router.Utils.split("/")
|
||||||
|
|
||||||
def call(conn = %{request_path: "/" <> unquote(only) <> _}, opts) do
|
def call(%{request_path: "/" <> unquote(only) <> _} = conn, opts) do
|
||||||
call_static(
|
call_static(
|
||||||
conn,
|
conn,
|
||||||
opts,
|
opts,
|
||||||
|
|
|
@ -6,11 +6,9 @@ defmodule Pleroma.Plugs.OAuthPlug do
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias Pleroma.{
|
alias Pleroma.User
|
||||||
User,
|
alias Pleroma.Repo
|
||||||
Repo,
|
alias Pleroma.Web.OAuth.Token
|
||||||
Web.OAuth.Token
|
|
||||||
}
|
|
||||||
|
|
||||||
@realm_reg Regex.compile!("Bearer\:?\s+(.*)$", "i")
|
@realm_reg Regex.compile!("Bearer\:?\s+(.*)$", "i")
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ def init(_opts) do
|
||||||
%{static_plug_opts: static_plug_opts}
|
%{static_plug_opts: static_plug_opts}
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(conn = %{request_path: <<"/", @path, "/", file::binary>>}, opts) do
|
def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do
|
||||||
config = Pleroma.Config.get([Pleroma.Upload])
|
config = Pleroma.Config.get([Pleroma.Upload])
|
||||||
|
|
||||||
with uploader <- Keyword.fetch!(config, :uploader),
|
with uploader <- Keyword.fetch!(config, :uploader),
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Plugs.UserFetcherPlug do
|
defmodule Pleroma.Plugs.UserFetcherPlug do
|
||||||
import Plug.Conn
|
|
||||||
alias Pleroma.Repo
|
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
|
import Plug.Conn
|
||||||
|
|
||||||
def init(options) do
|
def init(options) do
|
||||||
options
|
options
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Stats do
|
defmodule Pleroma.Stats do
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
alias Pleroma.{User, Repo}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
def start_link do
|
def start_link do
|
||||||
agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__)
|
agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__)
|
||||||
|
@ -23,7 +24,7 @@ def get_peers do
|
||||||
def schedule_update do
|
def schedule_update do
|
||||||
spawn(fn ->
|
spawn(fn ->
|
||||||
# 1 hour
|
# 1 hour
|
||||||
Process.sleep(1000 * 60 * 60 * 1)
|
Process.sleep(1000 * 60 * 60)
|
||||||
schedule_update()
|
schedule_update()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ defp prepare_upload(%{"img" => "data:image/" <> image_data}, opts) do
|
||||||
end
|
end
|
||||||
|
|
||||||
# For Mix.Tasks.MigrateLocalUploads
|
# For Mix.Tasks.MigrateLocalUploads
|
||||||
defp prepare_upload(upload = %__MODULE__{tempfile: path}, _opts) do
|
defp prepare_upload(%__MODULE__{tempfile: path} = upload, _opts) do
|
||||||
with {:ok, content_type} <- Pleroma.MIME.file_mime_type(path) do
|
with {:ok, content_type} <- Pleroma.MIME.file_mime_type(path) do
|
||||||
{:ok, %__MODULE__{upload | content_type: content_type}}
|
{:ok, %__MODULE__{upload | content_type: content_type}}
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ defmodule Pleroma.Upload.Filter.Dedupe do
|
||||||
@behaviour Pleroma.Upload.Filter
|
@behaviour Pleroma.Upload.Filter
|
||||||
alias Pleroma.Upload
|
alias Pleroma.Upload
|
||||||
|
|
||||||
def filter(upload = %Upload{name: name}) do
|
def filter(%Upload{name: name} = upload) do
|
||||||
extension = String.split(name, ".") |> List.last()
|
extension = String.split(name, ".") |> List.last()
|
||||||
shasum = :crypto.hash(:sha256, File.read!(upload.tempfile)) |> Base.encode16(case: :lower)
|
shasum = :crypto.hash(:sha256, File.read!(upload.tempfile)) |> Base.encode16(case: :lower)
|
||||||
filename = shasum <> "." <> extension
|
filename = shasum <> "." <> extension
|
||||||
|
|
|
@ -27,7 +27,7 @@ def get_file(file) do
|
||||||
])}}
|
])}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def put_file(upload = %Pleroma.Upload{}) do
|
def put_file(%Pleroma.Upload{} = upload) do
|
||||||
config = Pleroma.Config.get([__MODULE__])
|
config = Pleroma.Config.get([__MODULE__])
|
||||||
bucket = Keyword.get(config, :bucket)
|
bucket = Keyword.get(config, :bucket)
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,23 @@
|
||||||
defmodule Pleroma.User do
|
defmodule Pleroma.User do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
import Ecto.{Changeset, Query}
|
import Ecto.Changeset
|
||||||
alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Web
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Notification
|
||||||
alias Comeonin.Pbkdf2
|
alias Comeonin.Pbkdf2
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
|
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
|
||||||
alias Pleroma.Web.{OStatus, Websub, OAuth}
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
|
alias Pleroma.Web.Websub
|
||||||
|
alias Pleroma.Web.OAuth
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@ -96,12 +106,6 @@ def ap_followers(%User{} = user) do
|
||||||
"#{ap_id(user)}/followers"
|
"#{ap_id(user)}/followers"
|
||||||
end
|
end
|
||||||
|
|
||||||
def follow_changeset(struct, params \\ %{}) do
|
|
||||||
struct
|
|
||||||
|> cast(params, [:following])
|
|
||||||
|> validate_required([:following])
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_info(%User{} = user) do
|
def user_info(%User{} = user) do
|
||||||
oneself = if user.local, do: 1, else: 0
|
oneself = if user.local, do: 1, else: 0
|
||||||
|
|
||||||
|
@ -256,8 +260,8 @@ defp autofollow_users(user) do
|
||||||
@doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"
|
@doc "Inserts provided changeset, performs post-registration actions (confirmation email sending etc.)"
|
||||||
def register(%Ecto.Changeset{} = changeset) do
|
def register(%Ecto.Changeset{} = changeset) do
|
||||||
with {:ok, user} <- Repo.insert(changeset),
|
with {:ok, user} <- Repo.insert(changeset),
|
||||||
{:ok, _} <- try_send_confirmation_email(user),
|
{:ok, user} <- autofollow_users(user),
|
||||||
{:ok, user} <- autofollow_users(user) do
|
{:ok, _} <- try_send_confirmation_email(user) do
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -307,10 +311,13 @@ def maybe_follow(%User{} = follower, %User{info: _info} = followed) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "A mass follow for local users. Ignores blocks and has no side effects"
|
@doc "A mass follow for local users. Respects blocks but does not create activities."
|
||||||
@spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()}
|
@spec follow_all(User.t(), list(User.t())) :: {atom(), User.t()}
|
||||||
def follow_all(follower, followeds) do
|
def follow_all(follower, followeds) do
|
||||||
followed_addresses = Enum.map(followeds, fn %{follower_address: fa} -> fa end)
|
followed_addresses =
|
||||||
|
followeds
|
||||||
|
|> Enum.reject(fn %{ap_id: ap_id} -> ap_id in follower.info.blocks end)
|
||||||
|
|> Enum.map(fn %{follower_address: fa} -> fa end)
|
||||||
|
|
||||||
q =
|
q =
|
||||||
from(u in User,
|
from(u in User,
|
||||||
|
|
|
@ -23,6 +23,7 @@ defmodule Pleroma.User.Info do
|
||||||
field(:ap_enabled, :boolean, default: false)
|
field(:ap_enabled, :boolean, default: false)
|
||||||
field(:is_moderator, :boolean, default: false)
|
field(:is_moderator, :boolean, default: false)
|
||||||
field(:is_admin, :boolean, default: false)
|
field(:is_admin, :boolean, default: false)
|
||||||
|
field(:show_role, :boolean, default: true)
|
||||||
field(:keys, :string, default: nil)
|
field(:keys, :string, default: nil)
|
||||||
field(:settings, :map, default: nil)
|
field(:settings, :map, default: nil)
|
||||||
field(:magic_key, :string, default: nil)
|
field(:magic_key, :string, default: nil)
|
||||||
|
@ -31,7 +32,7 @@ defmodule Pleroma.User.Info do
|
||||||
field(:hub, :string, default: nil)
|
field(:hub, :string, default: nil)
|
||||||
field(:salmon, :string, default: nil)
|
field(:salmon, :string, default: nil)
|
||||||
field(:hide_followers, :boolean, default: false)
|
field(:hide_followers, :boolean, default: false)
|
||||||
field(:hide_followings, :boolean, default: false)
|
field(:hide_follows, :boolean, default: false)
|
||||||
field(:pinned_activities, {:array, :string}, default: [])
|
field(:pinned_activities, {:array, :string}, default: [])
|
||||||
|
|
||||||
# Found in the wild
|
# Found in the wild
|
||||||
|
@ -144,9 +145,10 @@ def profile_update(info, params) do
|
||||||
:no_rich_text,
|
:no_rich_text,
|
||||||
:default_scope,
|
:default_scope,
|
||||||
:banner,
|
:banner,
|
||||||
:hide_followings,
|
:hide_follows,
|
||||||
:hide_followers,
|
:hide_followers,
|
||||||
:background
|
:background,
|
||||||
|
:show_role
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -196,7 +198,8 @@ def admin_api_update(info, params) do
|
||||||
info
|
info
|
||||||
|> cast(params, [
|
|> cast(params, [
|
||||||
:is_moderator,
|
:is_moderator,
|
||||||
:is_admin
|
:is_admin,
|
||||||
|
:show_role
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,22 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
alias Pleroma.{Activity, Repo, Object, Upload, User, Notification, Instances}
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Web.ActivityPub.{Transmogrifier, MRF}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Upload
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Notification
|
||||||
|
alias Pleroma.Instances
|
||||||
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
alias Pleroma.Web.ActivityPub.MRF
|
||||||
alias Pleroma.Web.WebFinger
|
alias Pleroma.Web.WebFinger
|
||||||
alias Pleroma.Web.Federator
|
alias Pleroma.Web.Federator
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.OStatus
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
import Pleroma.Web.ActivityPub.Utils
|
import Pleroma.Web.ActivityPub.Utils
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
|
@ -19,10 +28,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
defp get_recipients(%{"type" => "Announce"} = data) do
|
defp get_recipients(%{"type" => "Announce"} = data) do
|
||||||
to = data["to"] || []
|
to = data["to"] || []
|
||||||
cc = data["cc"] || []
|
cc = data["cc"] || []
|
||||||
recipients = to ++ cc
|
|
||||||
actor = User.get_cached_by_ap_id(data["actor"])
|
actor = User.get_cached_by_ap_id(data["actor"])
|
||||||
|
|
||||||
recipients
|
recipients =
|
||||||
|
(to ++ cc)
|
||||||
|> Enum.filter(fn recipient ->
|
|> Enum.filter(fn recipient ->
|
||||||
case User.get_cached_by_ap_id(recipient) do
|
case User.get_cached_by_ap_id(recipient) do
|
||||||
nil ->
|
nil ->
|
||||||
|
@ -119,7 +128,7 @@ def stream_out(activity) do
|
||||||
activity.data["object"]
|
activity.data["object"]
|
||||||
|> Map.get("tag", [])
|
|> Map.get("tag", [])
|
||||||
|> Enum.filter(fn tag -> is_bitstring(tag) end)
|
|> Enum.filter(fn tag -> is_bitstring(tag) end)
|
||||||
|> Enum.map(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end)
|
|> Enum.each(fn tag -> Pleroma.Web.Streamer.stream("hashtag:" <> tag, activity) end)
|
||||||
|
|
||||||
if activity.data["object"]["attachment"] != [] do
|
if activity.data["object"]["attachment"] != [] do
|
||||||
Pleroma.Web.Streamer.stream("public:media", activity)
|
Pleroma.Web.Streamer.stream("public:media", activity)
|
||||||
|
|
|
@ -5,12 +5,15 @@
|
||||||
defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.{Activity, User, Object}
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Web.ActivityPub.{ObjectView, UserView}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectView
|
||||||
|
alias Pleroma.Web.ActivityPub.UserView
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.Federator
|
alias Pleroma.Web.Federator
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
73
lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
Normal file
73
lib/pleroma/web/activity_pub/mrf/keyword_policy.ex
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicy do
|
||||||
|
@behaviour Pleroma.Web.ActivityPub.MRF
|
||||||
|
defp string_matches?(string, pattern) when is_binary(pattern) do
|
||||||
|
String.contains?(string, pattern)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp string_matches?(string, pattern) do
|
||||||
|
String.match?(string, pattern)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp check_reject(%{"object" => %{"content" => content}} = message) do
|
||||||
|
if Enum.any?(Pleroma.Config.get([:mrf_keyword, :reject]), fn pattern ->
|
||||||
|
string_matches?(content, pattern)
|
||||||
|
end) do
|
||||||
|
{:reject, nil}
|
||||||
|
else
|
||||||
|
{:ok, message}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp check_ftl_removal(%{"to" => to, "object" => %{"content" => content}} = message) do
|
||||||
|
if "https://www.w3.org/ns/activitystreams#Public" in to and
|
||||||
|
Enum.any?(Pleroma.Config.get([:mrf_keyword, :federated_timeline_removal]), fn pattern ->
|
||||||
|
string_matches?(content, pattern)
|
||||||
|
end) do
|
||||||
|
to = List.delete(to, "https://www.w3.org/ns/activitystreams#Public")
|
||||||
|
cc = ["https://www.w3.org/ns/activitystreams#Public" | message["cc"] || []]
|
||||||
|
|
||||||
|
message =
|
||||||
|
message
|
||||||
|
|> Map.put("to", to)
|
||||||
|
|> Map.put("cc", cc)
|
||||||
|
|
||||||
|
{:ok, message}
|
||||||
|
else
|
||||||
|
{:ok, message}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp check_replace(%{"object" => %{"content" => content}} = message) do
|
||||||
|
content =
|
||||||
|
Enum.reduce(Pleroma.Config.get([:mrf_keyword, :replace]), content, fn {pattern, replacement},
|
||||||
|
acc ->
|
||||||
|
String.replace(acc, pattern, replacement)
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:ok, put_in(message["object"]["content"], content)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def filter(%{"object" => %{"content" => nil}} = message) do
|
||||||
|
{:ok, message}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def filter(%{"type" => "Create", "object" => %{"content" => _content}} = message) do
|
||||||
|
with {:ok, message} <- check_reject(message),
|
||||||
|
{:ok, message} <- check_ftl_removal(message),
|
||||||
|
{:ok, message} <- check_replace(message) do
|
||||||
|
{:ok, message}
|
||||||
|
else
|
||||||
|
_e ->
|
||||||
|
{:reject, nil}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def filter(message), do: {:ok, message}
|
||||||
|
end
|
|
@ -3,7 +3,9 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.Relay do
|
defmodule Pleroma.Web.ActivityPub.Relay do
|
||||||
alias Pleroma.{User, Object, Activity}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
A module to handle coding from internal to wire ActivityPub and back.
|
A module to handle coding from internal to wire ActivityPub and back.
|
||||||
"""
|
"""
|
||||||
|
alias Pleroma.Activity
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Activity
|
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
|
|
@ -3,11 +3,19 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.Utils do
|
defmodule Pleroma.Web.ActivityPub.Utils do
|
||||||
alias Pleroma.{Repo, Web, Object, Activity, User, Notification}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Web
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Web.Router.Helpers
|
alias Pleroma.Web.Router.Helpers
|
||||||
alias Pleroma.Web.Endpoint
|
alias Pleroma.Web.Endpoint
|
||||||
alias Ecto.{Changeset, UUID}
|
alias Ecto.Changeset
|
||||||
|
alias Ecto.UUID
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@supported_object_types ["Article", "Note", "Video", "Page"]
|
@supported_object_types ["Article", "Note", "Video", "Page"]
|
||||||
|
@ -134,14 +142,8 @@ def create_context(context) do
|
||||||
context = context || generate_id("contexts")
|
context = context || generate_id("contexts")
|
||||||
changeset = Object.context_mapping(context)
|
changeset = Object.context_mapping(context)
|
||||||
|
|
||||||
case Repo.insert(changeset) do
|
with {:ok, object} <- Object.insert_or_get(changeset) do
|
||||||
{:ok, object} ->
|
|
||||||
object
|
object
|
||||||
|
|
||||||
# This should be solved by an upsert, but it seems ecto
|
|
||||||
# has problems accessing the constraint inside the jsonb.
|
|
||||||
{:error, _} ->
|
|
||||||
Object.get_cached_by_ap_id(context)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.ObjectView do
|
defmodule Pleroma.Web.ActivityPub.ObjectView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.{Object, Activity}
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
|
||||||
def render("object.json", %{object: %Object{} = object}) do
|
def render("object.json", %{object: %Object{} = object}) do
|
||||||
|
|
|
@ -4,13 +4,15 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.ActivityPub.UserView do
|
defmodule Pleroma.Web.ActivityPub.UserView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.Web.Salmon
|
|
||||||
alias Pleroma.Web.WebFinger
|
alias Pleroma.Web.WebFinger
|
||||||
|
alias Pleroma.Web.Salmon
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
# the instance itself is not a Person, but instead an Application
|
# the instance itself is not a Person, but instead an Application
|
||||||
|
@ -86,7 +88,7 @@ def render("following.json", %{user: user, page: page}) do
|
||||||
query = from(user in query, select: [:ap_id])
|
query = from(user in query, select: [:ap_id])
|
||||||
following = Repo.all(query)
|
following = Repo.all(query)
|
||||||
|
|
||||||
collection(following, "#{user.ap_id}/following", page, !user.info.hide_followings)
|
collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows)
|
||||||
|> Map.merge(Utils.make_json_ld_header())
|
|> Map.merge(Utils.make_json_ld_header())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ def render("following.json", %{user: user}) do
|
||||||
"id" => "#{user.ap_id}/following",
|
"id" => "#{user.ap_id}/following",
|
||||||
"type" => "OrderedCollection",
|
"type" => "OrderedCollection",
|
||||||
"totalItems" => length(following),
|
"totalItems" => length(following),
|
||||||
"first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_followings)
|
"first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows)
|
||||||
}
|
}
|
||||||
|> Map.merge(Utils.make_json_ld_header())
|
|> Map.merge(Utils.make_json_ld_header())
|
||||||
end
|
end
|
||||||
|
@ -239,6 +241,8 @@ def collection(collection, iri, page, show_items \\ true, total \\ nil) do
|
||||||
|
|
||||||
if offset < total do
|
if offset < total do
|
||||||
Map.put(map, "next", "#{iri}?page=#{page + 1}")
|
Map.put(map, "next", "#{iri}?page=#{page + 1}")
|
||||||
|
else
|
||||||
|
map
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.CommonAPI do
|
defmodule Pleroma.Web.CommonAPI do
|
||||||
alias Pleroma.{User, Repo, Activity, Object}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
|
|
|
@ -5,12 +5,15 @@
|
||||||
defmodule Pleroma.Web.CommonAPI.Utils do
|
defmodule Pleroma.Web.CommonAPI.Utils do
|
||||||
alias Calendar.Strftime
|
alias Calendar.Strftime
|
||||||
alias Comeonin.Pbkdf2
|
alias Comeonin.Pbkdf2
|
||||||
alias Pleroma.{Activity, Formatter, Object, Repo}
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Formatter
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
|
||||||
alias Pleroma.Web.Endpoint
|
alias Pleroma.Web.Endpoint
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
|
||||||
# This is a hack for twidere.
|
# This is a hack for twidere.
|
||||||
def get_by_id_or_ap_id(id) do
|
def get_by_id_or_ap_id(id) do
|
||||||
|
@ -95,7 +98,7 @@ def make_content_html(
|
||||||
def make_context(%Activity{data: %{"context" => context}}), do: context
|
def make_context(%Activity{data: %{"context" => context}}), do: context
|
||||||
def make_context(_), do: Utils.generate_context_id()
|
def make_context(_), do: Utils.generate_context_id()
|
||||||
|
|
||||||
def maybe_add_attachments(text, _attachments, _no_links = true), do: text
|
def maybe_add_attachments(text, _attachments, true = _no_links), do: text
|
||||||
|
|
||||||
def maybe_add_attachments(text, attachments, _no_links) do
|
def maybe_add_attachments(text, attachments, _no_links) do
|
||||||
add_attachments(text, attachments)
|
add_attachments(text, attachments)
|
||||||
|
|
|
@ -3,16 +3,19 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Federator do
|
defmodule Pleroma.Web.Federator do
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Jobs
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.{WebFinger, Websub, Salmon}
|
alias Pleroma.Web.WebFinger
|
||||||
alias Pleroma.Web.Federator.RetryQueue
|
alias Pleroma.Web.Websub
|
||||||
|
alias Pleroma.Web.Salmon
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Relay
|
alias Pleroma.Web.ActivityPub.Relay
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
alias Pleroma.Web.Federator.RetryQueue
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.OStatus
|
||||||
|
alias Pleroma.Jobs
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@websub Application.get_env(:pleroma, :websub)
|
@websub Application.get_env(:pleroma, :websub)
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
# https://tools.ietf.org/html/draft-cavage-http-signatures-08
|
# https://tools.ietf.org/html/draft-cavage-http-signatures-08
|
||||||
defmodule Pleroma.Web.HTTPSignatures do
|
defmodule Pleroma.Web.HTTPSignatures do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def split_signature(sig) do
|
def split_signature(sig) do
|
||||||
|
|
|
@ -4,34 +4,44 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
alias Pleroma.{Repo, Object, Activity, User, Notification, Stats}
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Filter
|
||||||
|
alias Pleroma.Notification
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Stats
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
alias Pleroma.Web.MediaProxy
|
||||||
|
alias Pleroma.Web.Push
|
||||||
|
alias Push.Subscription
|
||||||
|
|
||||||
alias Pleroma.Web.MastodonAPI.{
|
alias Pleroma.Web.MastodonAPI.AccountView
|
||||||
StatusView,
|
alias Pleroma.Web.MastodonAPI.FilterView
|
||||||
AccountView,
|
alias Pleroma.Web.MastodonAPI.ListView
|
||||||
MastodonView,
|
alias Pleroma.Web.MastodonAPI.MastodonView
|
||||||
ListView,
|
alias Pleroma.Web.MastodonAPI.PushSubscriptionView
|
||||||
FilterView,
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
PushSubscriptionView
|
|
||||||
}
|
|
||||||
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.OAuth.App
|
||||||
alias Pleroma.Web.OAuth.{Authorization, Token, App}
|
alias Pleroma.Web.OAuth.Authorization
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.OAuth.Token
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
|
@local_mastodon_name "Mastodon-Local"
|
||||||
|
|
||||||
action_fallback(:errors)
|
action_fallback(:errors)
|
||||||
|
|
||||||
def create_app(conn, params) do
|
def create_app(conn, params) do
|
||||||
with cs <- App.register_changeset(%App{}, params) |> IO.inspect(),
|
with cs <- App.register_changeset(%App{}, params),
|
||||||
{:ok, app} <- Repo.insert(cs) |> IO.inspect() do
|
false <- cs.changes[:client_name] == @local_mastodon_name,
|
||||||
|
{:ok, app} <- Repo.insert(cs) do
|
||||||
res = %{
|
res = %{
|
||||||
id: app.id |> to_string,
|
id: app.id |> to_string,
|
||||||
name: app.client_name,
|
name: app.client_name,
|
||||||
|
@ -129,7 +139,7 @@ def user(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
|
||||||
@mastodon_api_level "2.5.0"
|
@mastodon_api_level "2.5.0"
|
||||||
|
|
||||||
def masto_instance(conn, _params) do
|
def masto_instance(conn, _params) do
|
||||||
instance = Pleroma.Config.get(:instance)
|
instance = Config.get(:instance)
|
||||||
|
|
||||||
response = %{
|
response = %{
|
||||||
uri: Web.base_url(),
|
uri: Web.base_url(),
|
||||||
|
@ -225,7 +235,8 @@ def home_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|> Map.put("user", user)
|
|> Map.put("user", user)
|
||||||
|
|
||||||
activities =
|
activities =
|
||||||
ActivityPub.fetch_activities([user.ap_id | user.following], params)
|
[user.ap_id | user.following]
|
||||||
|
|> ActivityPub.fetch_activities(params)
|
||||||
|> ActivityPub.contain_timeline(user)
|
|> ActivityPub.contain_timeline(user)
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
|
@ -238,14 +249,12 @@ def home_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
def public_timeline(%{assigns: %{user: user}} = conn, params) do
|
def public_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
local_only = params["local"] in [true, "True", "true", "1"]
|
local_only = params["local"] in [true, "True", "true", "1"]
|
||||||
|
|
||||||
params =
|
activities =
|
||||||
params
|
params
|
||||||
|> Map.put("type", ["Create", "Announce"])
|
|> Map.put("type", ["Create", "Announce"])
|
||||||
|> Map.put("local_only", local_only)
|
|> Map.put("local_only", local_only)
|
||||||
|> Map.put("blocking_user", user)
|
|> Map.put("blocking_user", user)
|
||||||
|
|> ActivityPub.fetch_public_activities()
|
||||||
activities =
|
|
||||||
ActivityPub.fetch_public_activities(params)
|
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -314,6 +323,7 @@ def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
as: :activity
|
as: :activity
|
||||||
)
|
)
|
||||||
|> Enum.reverse(),
|
|> Enum.reverse(),
|
||||||
|
# credo:disable-for-previous-line Credo.Check.Refactor.PipeChainStart
|
||||||
descendants:
|
descendants:
|
||||||
StatusView.render(
|
StatusView.render(
|
||||||
"index.json",
|
"index.json",
|
||||||
|
@ -322,6 +332,7 @@ def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
as: :activity
|
as: :activity
|
||||||
)
|
)
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
# credo:disable-for-previous-line Credo.Check.Refactor.PipeChainStart
|
||||||
}
|
}
|
||||||
|
|
||||||
json(conn, result)
|
json(conn, result)
|
||||||
|
@ -449,9 +460,8 @@ def notifications(%{assigns: %{user: user}} = conn, params) do
|
||||||
notifications = Notification.for_user(user, params)
|
notifications = Notification.for_user(user, params)
|
||||||
|
|
||||||
result =
|
result =
|
||||||
Enum.map(notifications, fn x ->
|
notifications
|
||||||
render_notification(user, x)
|
|> Enum.map(fn x -> render_notification(user, x) end)
|
||||||
end)
|
|
||||||
|> Enum.filter(& &1)
|
|> Enum.filter(& &1)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -580,7 +590,7 @@ def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
[]
|
[]
|
||||||
|> Enum.map(&String.downcase(&1))
|
|> Enum.map(&String.downcase(&1))
|
||||||
|
|
||||||
query_params =
|
activities =
|
||||||
params
|
params
|
||||||
|> Map.put("type", "Create")
|
|> Map.put("type", "Create")
|
||||||
|> Map.put("local_only", local_only)
|
|> Map.put("local_only", local_only)
|
||||||
|
@ -588,9 +598,7 @@ def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|> Map.put("tag", tags)
|
|> Map.put("tag", tags)
|
||||||
|> Map.put("tag_all", tag_all)
|
|> Map.put("tag_all", tag_all)
|
||||||
|> Map.put("tag_reject", tag_reject)
|
|> Map.put("tag_reject", tag_reject)
|
||||||
|
|> ActivityPub.fetch_public_activities()
|
||||||
activities =
|
|
||||||
ActivityPub.fetch_public_activities(query_params)
|
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -621,7 +629,7 @@ def following(%{assigns: %{user: for_user}} = conn, %{"id" => id}) do
|
||||||
followers =
|
followers =
|
||||||
cond do
|
cond do
|
||||||
for_user && user.id == for_user.id -> followers
|
for_user && user.id == for_user.id -> followers
|
||||||
user.info.hide_followings -> []
|
user.info.hide_follows -> []
|
||||||
true -> followers
|
true -> followers
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -690,7 +698,7 @@ def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
|
||||||
{:ok, _activity} <- ActivityPub.follow(follower, followed),
|
{:ok, _activity} <- ActivityPub.follow(follower, followed),
|
||||||
{:ok, follower, followed} <-
|
{:ok, follower, followed} <-
|
||||||
User.wait_and_refresh(
|
User.wait_and_refresh(
|
||||||
Pleroma.Config.get([:activitypub, :follow_handshake_timeout]),
|
Config.get([:activitypub, :follow_handshake_timeout]),
|
||||||
follower,
|
follower,
|
||||||
followed
|
followed
|
||||||
) do
|
) do
|
||||||
|
@ -819,7 +827,8 @@ def search2(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||||
tags_path = Web.base_url() <> "/tag/"
|
tags_path = Web.base_url() <> "/tag/"
|
||||||
|
|
||||||
tags =
|
tags =
|
||||||
String.split(query)
|
query
|
||||||
|
|> String.split()
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
||||||
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
||||||
|
@ -841,7 +850,8 @@ def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
|
||||||
statuses = status_search(user, query)
|
statuses = status_search(user, query)
|
||||||
|
|
||||||
tags =
|
tags =
|
||||||
String.split(query)
|
query
|
||||||
|
|> String.split()
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
|> Enum.filter(fn tag -> String.starts_with?(tag, "#") end)
|
||||||
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
|> Enum.map(fn tag -> String.slice(tag, 1..-1) end)
|
||||||
|
@ -865,14 +875,12 @@ def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) d
|
||||||
end
|
end
|
||||||
|
|
||||||
def favourites(%{assigns: %{user: user}} = conn, params) do
|
def favourites(%{assigns: %{user: user}} = conn, params) do
|
||||||
params =
|
activities =
|
||||||
params
|
params
|
||||||
|> Map.put("type", "Create")
|
|> Map.put("type", "Create")
|
||||||
|> Map.put("favorited_by", user.ap_id)
|
|> Map.put("favorited_by", user.ap_id)
|
||||||
|> Map.put("blocking_user", user)
|
|> Map.put("blocking_user", user)
|
||||||
|
|> ActivityPub.fetch_public_activities()
|
||||||
activities =
|
|
||||||
ActivityPub.fetch_public_activities(params)
|
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -988,12 +996,10 @@ def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params)
|
||||||
|
|
||||||
# we must filter the following list for the user to avoid leaking statuses the user
|
# we must filter the following list for the user to avoid leaking statuses the user
|
||||||
# does not actually have permission to see (for more info, peruse security issue #270).
|
# does not actually have permission to see (for more info, peruse security issue #270).
|
||||||
following_to =
|
activities =
|
||||||
following
|
following
|
||||||
|> Enum.filter(fn x -> x in user.following end)
|
|> Enum.filter(fn x -> x in user.following end)
|
||||||
|
|> ActivityPub.fetch_activities_bounded(following, params)
|
||||||
activities =
|
|
||||||
ActivityPub.fetch_activities_bounded(following_to, following, params)
|
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -1015,7 +1021,7 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
if user && token do
|
if user && token do
|
||||||
mastodon_emoji = mastodonized_emoji()
|
mastodon_emoji = mastodonized_emoji()
|
||||||
|
|
||||||
limit = Pleroma.Config.get([:instance, :limit])
|
limit = Config.get([:instance, :limit])
|
||||||
|
|
||||||
accounts =
|
accounts =
|
||||||
Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user}))
|
Map.put(%{}, user.id, AccountView.render("account.json", %{user: user, for: user}))
|
||||||
|
@ -1039,8 +1045,8 @@ def index(%{assigns: %{user: user}} = conn, _params) do
|
||||||
max_toot_chars: limit
|
max_toot_chars: limit
|
||||||
},
|
},
|
||||||
rights: %{
|
rights: %{
|
||||||
delete_others_notice: !!user.info.is_moderator,
|
delete_others_notice: present?(user.info.is_moderator),
|
||||||
admin: !!user.info.is_admin
|
admin: present?(user.info.is_admin)
|
||||||
},
|
},
|
||||||
compose: %{
|
compose: %{
|
||||||
me: "#{user.id}",
|
me: "#{user.id}",
|
||||||
|
@ -1154,16 +1160,13 @@ def login(conn, _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_or_make_app() do
|
defp get_or_make_app() do
|
||||||
with %App{} = app <- Repo.get_by(App, client_name: "Mastodon-Local") do
|
find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."}
|
||||||
|
|
||||||
|
with %App{} = app <- Repo.get_by(App, find_attrs) do
|
||||||
{:ok, app}
|
{:ok, app}
|
||||||
else
|
else
|
||||||
_e ->
|
_e ->
|
||||||
cs =
|
cs = App.register_changeset(%App{}, Map.put(find_attrs, :scopes, "read,write,follow"))
|
||||||
App.register_changeset(%App{}, %{
|
|
||||||
client_name: "Mastodon-Local",
|
|
||||||
redirect_uris: ".",
|
|
||||||
scopes: "read,write,follow"
|
|
||||||
})
|
|
||||||
|
|
||||||
Repo.insert(cs)
|
Repo.insert(cs)
|
||||||
end
|
end
|
||||||
|
@ -1235,7 +1238,7 @@ def render_notification(user, %{id: id, activity: activity, inserted_at: created
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_filters(%{assigns: %{user: user}} = conn, _) do
|
def get_filters(%{assigns: %{user: user}} = conn, _) do
|
||||||
filters = Pleroma.Filter.get_filters(user)
|
filters = Filter.get_filters(user)
|
||||||
res = FilterView.render("filters.json", filters: filters)
|
res = FilterView.render("filters.json", filters: filters)
|
||||||
json(conn, res)
|
json(conn, res)
|
||||||
end
|
end
|
||||||
|
@ -1244,7 +1247,7 @@ def create_filter(
|
||||||
%{assigns: %{user: user}} = conn,
|
%{assigns: %{user: user}} = conn,
|
||||||
%{"phrase" => phrase, "context" => context} = params
|
%{"phrase" => phrase, "context" => context} = params
|
||||||
) do
|
) do
|
||||||
query = %Pleroma.Filter{
|
query = %Filter{
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
phrase: phrase,
|
phrase: phrase,
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -1253,13 +1256,13 @@ def create_filter(
|
||||||
# expires_at
|
# expires_at
|
||||||
}
|
}
|
||||||
|
|
||||||
{:ok, response} = Pleroma.Filter.create(query)
|
{:ok, response} = Filter.create(query)
|
||||||
res = FilterView.render("filter.json", filter: response)
|
res = FilterView.render("filter.json", filter: response)
|
||||||
json(conn, res)
|
json(conn, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id}) do
|
def get_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id}) do
|
||||||
filter = Pleroma.Filter.get(filter_id, user)
|
filter = Filter.get(filter_id, user)
|
||||||
res = FilterView.render("filter.json", filter: filter)
|
res = FilterView.render("filter.json", filter: filter)
|
||||||
json(conn, res)
|
json(conn, res)
|
||||||
end
|
end
|
||||||
|
@ -1268,7 +1271,7 @@ def update_filter(
|
||||||
%{assigns: %{user: user}} = conn,
|
%{assigns: %{user: user}} = conn,
|
||||||
%{"phrase" => phrase, "context" => context, "id" => filter_id} = params
|
%{"phrase" => phrase, "context" => context, "id" => filter_id} = params
|
||||||
) do
|
) do
|
||||||
query = %Pleroma.Filter{
|
query = %Filter{
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
filter_id: filter_id,
|
filter_id: filter_id,
|
||||||
phrase: phrase,
|
phrase: phrase,
|
||||||
|
@ -1278,32 +1281,32 @@ def update_filter(
|
||||||
# expires_at
|
# expires_at
|
||||||
}
|
}
|
||||||
|
|
||||||
{:ok, response} = Pleroma.Filter.update(query)
|
{:ok, response} = Filter.update(query)
|
||||||
res = FilterView.render("filter.json", filter: response)
|
res = FilterView.render("filter.json", filter: response)
|
||||||
json(conn, res)
|
json(conn, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id}) do
|
def delete_filter(%{assigns: %{user: user}} = conn, %{"id" => filter_id}) do
|
||||||
query = %Pleroma.Filter{
|
query = %Filter{
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
filter_id: filter_id
|
filter_id: filter_id
|
||||||
}
|
}
|
||||||
|
|
||||||
{:ok, _} = Pleroma.Filter.delete(query)
|
{:ok, _} = Filter.delete(query)
|
||||||
json(conn, %{})
|
json(conn, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_push_subscription(%{assigns: %{user: user, token: token}} = conn, params) do
|
def create_push_subscription(%{assigns: %{user: user, token: token}} = conn, params) do
|
||||||
true = Pleroma.Web.Push.enabled()
|
true = Push.enabled()
|
||||||
Pleroma.Web.Push.Subscription.delete_if_exists(user, token)
|
Subscription.delete_if_exists(user, token)
|
||||||
{:ok, subscription} = Pleroma.Web.Push.Subscription.create(user, token, params)
|
{:ok, subscription} = Subscription.create(user, token, params)
|
||||||
view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)
|
view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)
|
||||||
json(conn, view)
|
json(conn, view)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do
|
def get_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do
|
||||||
true = Pleroma.Web.Push.enabled()
|
true = Push.enabled()
|
||||||
subscription = Pleroma.Web.Push.Subscription.get(user, token)
|
subscription = Subscription.get(user, token)
|
||||||
view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)
|
view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)
|
||||||
json(conn, view)
|
json(conn, view)
|
||||||
end
|
end
|
||||||
|
@ -1312,15 +1315,15 @@ def update_push_subscription(
|
||||||
%{assigns: %{user: user, token: token}} = conn,
|
%{assigns: %{user: user, token: token}} = conn,
|
||||||
params
|
params
|
||||||
) do
|
) do
|
||||||
true = Pleroma.Web.Push.enabled()
|
true = Push.enabled()
|
||||||
{:ok, subscription} = Pleroma.Web.Push.Subscription.update(user, token, params)
|
{:ok, subscription} = Subscription.update(user, token, params)
|
||||||
view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)
|
view = PushSubscriptionView.render("push_subscription.json", subscription: subscription)
|
||||||
json(conn, view)
|
json(conn, view)
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do
|
def delete_push_subscription(%{assigns: %{user: user, token: token}} = conn, _params) do
|
||||||
true = Pleroma.Web.Push.enabled()
|
true = Push.enabled()
|
||||||
{:ok, _response} = Pleroma.Web.Push.Subscription.delete(user, token)
|
{:ok, _response} = Subscription.delete(user, token)
|
||||||
json(conn, %{})
|
json(conn, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1331,17 +1334,21 @@ def errors(conn, _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def suggestions(%{assigns: %{user: user}} = conn, _) do
|
def suggestions(%{assigns: %{user: user}} = conn, _) do
|
||||||
suggestions = Pleroma.Config.get(:suggestions)
|
suggestions = Config.get(:suggestions)
|
||||||
|
|
||||||
if Keyword.get(suggestions, :enabled, false) do
|
if Keyword.get(suggestions, :enabled, false) do
|
||||||
api = Keyword.get(suggestions, :third_party_engine, "")
|
api = Keyword.get(suggestions, :third_party_engine, "")
|
||||||
timeout = Keyword.get(suggestions, :timeout, 5000)
|
timeout = Keyword.get(suggestions, :timeout, 5000)
|
||||||
limit = Keyword.get(suggestions, :limit, 23)
|
limit = Keyword.get(suggestions, :limit, 23)
|
||||||
|
|
||||||
host = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
|
host = Config.get([Pleroma.Web.Endpoint, :url, :host])
|
||||||
|
|
||||||
user = user.nickname
|
user = user.nickname
|
||||||
url = String.replace(api, "{{host}}", host) |> String.replace("{{user}}", user)
|
|
||||||
|
url =
|
||||||
|
api
|
||||||
|
|> String.replace("{{host}}", host)
|
||||||
|
|> String.replace("{{user}}", user)
|
||||||
|
|
||||||
with {:ok, %{status: 200, body: body}} <-
|
with {:ok, %{status: 200, body: body}} <-
|
||||||
@httpoison.get(
|
@httpoison.get(
|
||||||
|
@ -1354,8 +1361,9 @@ def suggestions(%{assigns: %{user: user}} = conn, _) do
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
{:ok, data} <- Jason.decode(body) do
|
{:ok, data} <- Jason.decode(body) do
|
||||||
data2 =
|
data =
|
||||||
Enum.slice(data, 0, limit)
|
data
|
||||||
|
|> Enum.slice(0, limit)
|
||||||
|> Enum.map(fn x ->
|
|> Enum.map(fn x ->
|
||||||
Map.put(
|
Map.put(
|
||||||
x,
|
x,
|
||||||
|
@ -1374,7 +1382,7 @@ def suggestions(%{assigns: %{user: user}} = conn, _) do
|
||||||
end)
|
end)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> json(data2)
|
|> json(data)
|
||||||
else
|
else
|
||||||
e -> Logger.error("Could not retrieve suggestions at fetch #{url}, #{inspect(e)}")
|
e -> Logger.error("Could not retrieve suggestions at fetch #{url}, #{inspect(e)}")
|
||||||
end
|
end
|
||||||
|
@ -1417,4 +1425,8 @@ def try_render(conn, _, _) do
|
||||||
|> put_status(501)
|
|> put_status(501)
|
||||||
|> json(%{error: "Can't display this activity"})
|
|> json(%{error: "Can't display this activity"})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp present?(nil), do: false
|
||||||
|
defp present?(false), do: false
|
||||||
|
defp present?(_), do: true
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.AccountView do
|
defmodule Pleroma.Web.MastodonAPI.AccountView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Web.MastodonAPI.AccountView
|
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
|
||||||
alias Pleroma.Web.MediaProxy
|
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
|
alias Pleroma.Web.MastodonAPI.AccountView
|
||||||
|
alias Pleroma.Web.MediaProxy
|
||||||
|
|
||||||
def render("accounts.json", %{users: users} = opts) do
|
def render("accounts.json", %{users: users} = opts) do
|
||||||
users
|
users
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.MastodonAPI.FilterView do
|
defmodule Pleroma.Web.MastodonAPI.FilterView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.Web.MastodonAPI.FilterView
|
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
|
alias Pleroma.Web.MastodonAPI.FilterView
|
||||||
|
|
||||||
def render("filters.json", %{filters: filters} = opts) do
|
def render("filters.json", %{filters: filters} = opts) do
|
||||||
render_many(filters, FilterView, "filter.json", opts)
|
render_many(filters, FilterView, "filter.json", opts)
|
||||||
|
|
|
@ -10,9 +10,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
alias Pleroma.Web.MediaProxy
|
|
||||||
alias Pleroma.Web.MastodonAPI.AccountView
|
alias Pleroma.Web.MastodonAPI.AccountView
|
||||||
alias Pleroma.Web.MastodonAPI.StatusView
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
|
alias Pleroma.Web.MediaProxy
|
||||||
|
|
||||||
# TODO: Add cached version.
|
# TODO: Add cached version.
|
||||||
defp get_replied_to_activities(activities) do
|
defp get_replied_to_activities(activities) do
|
||||||
|
@ -182,11 +182,13 @@ def render("status.json", _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("card.json", %{rich_media: rich_media, page_url: page_url}) do
|
def render("card.json", %{rich_media: rich_media, page_url: page_url}) do
|
||||||
|
page_url_data = URI.parse(page_url)
|
||||||
|
|
||||||
page_url_data =
|
page_url_data =
|
||||||
if rich_media[:url] != nil do
|
if rich_media[:url] != nil do
|
||||||
URI.merge(URI.parse(page_url), URI.parse(rich_media[:url]))
|
URI.merge(page_url_data, URI.parse(rich_media[:url]))
|
||||||
else
|
else
|
||||||
page_url
|
page_url_data
|
||||||
end
|
end
|
||||||
|
|
||||||
page_url = page_url_data |> to_string
|
page_url = page_url_data |> to_string
|
||||||
|
|
|
@ -6,7 +6,8 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
alias Pleroma.Web.OAuth.Token
|
alias Pleroma.Web.OAuth.Token
|
||||||
alias Pleroma.{User, Repo}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
@behaviour :cowboy_websocket_handler
|
@behaviour :cowboy_websocket_handler
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,12 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.MediaProxy.MediaProxyController do
|
defmodule Pleroma.Web.MediaProxy.MediaProxyController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
alias Pleroma.{Web.MediaProxy, ReverseProxy}
|
alias Pleroma.ReverseProxy
|
||||||
|
alias Pleroma.Web.MediaProxy
|
||||||
|
|
||||||
@default_proxy_opts [max_body_length: 25 * 1_048_576, http: [follow_redirect: true]]
|
@default_proxy_opts [max_body_length: 25 * 1_048_576, http: [follow_redirect: true]]
|
||||||
|
|
||||||
def remote(conn, params = %{"sig" => sig64, "url" => url64}) do
|
def remote(conn, %{"sig" => sig64, "url" => url64} = params) do
|
||||||
with config <- Pleroma.Config.get([:media_proxy], []),
|
with config <- Pleroma.Config.get([:media_proxy], []),
|
||||||
true <- Keyword.get(config, :enabled, false),
|
true <- Keyword.get(config, :enabled, false),
|
||||||
{:ok, url} <- MediaProxy.decode_url(sig64, url64),
|
{:ok, url} <- MediaProxy.decode_url(sig64, url64),
|
||||||
|
|
|
@ -9,7 +9,7 @@ def url(nil), do: nil
|
||||||
|
|
||||||
def url(""), do: nil
|
def url(""), do: nil
|
||||||
|
|
||||||
def url(url = "/" <> _), do: url
|
def url("/" <> _ = url), do: url
|
||||||
|
|
||||||
def url(url) do
|
def url(url) do
|
||||||
config = Application.get_env(:pleroma, :media_proxy, [])
|
config = Application.get_env(:pleroma, :media_proxy, [])
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Metadata.Providers.OpenGraph do
|
defmodule Pleroma.Web.Metadata.Providers.OpenGraph do
|
||||||
alias Pleroma.Web.Metadata.Providers.Provider
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.Formatter
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.Metadata
|
alias Pleroma.Web.Metadata
|
||||||
alias Pleroma.{HTML, Formatter, User}
|
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
|
alias Pleroma.Web.Metadata.Providers.Provider
|
||||||
|
|
||||||
@behaviour Provider
|
@behaviour Provider
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.Stats
|
|
||||||
alias Pleroma.Web
|
|
||||||
alias Pleroma.{User, Repo}
|
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Stats
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.ActivityPub.MRF
|
alias Pleroma.Web.ActivityPub.MRF
|
||||||
|
|
||||||
plug(Pleroma.Web.FederatingPlug)
|
plug(Pleroma.Web.FederatingPlug)
|
||||||
|
@ -32,7 +33,7 @@ def schemas(conn, _params) do
|
||||||
|
|
||||||
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
|
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
|
||||||
# under software.
|
# under software.
|
||||||
def raw_nodeinfo() do
|
def raw_nodeinfo do
|
||||||
instance = Application.get_env(:pleroma, :instance)
|
instance = Application.get_env(:pleroma, :instance)
|
||||||
media_proxy = Application.get_env(:pleroma, :media_proxy)
|
media_proxy = Application.get_env(:pleroma, :media_proxy)
|
||||||
suggestions = Application.get_env(:pleroma, :suggestions)
|
suggestions = Application.get_env(:pleroma, :suggestions)
|
||||||
|
@ -44,6 +45,33 @@ def raw_nodeinfo() do
|
||||||
Application.get_env(:pleroma, :mrf_simple)
|
Application.get_env(:pleroma, :mrf_simple)
|
||||||
|> Enum.into(%{})
|
|> Enum.into(%{})
|
||||||
|
|
||||||
|
# This horror is needed to convert regex sigils to strings
|
||||||
|
mrf_keyword =
|
||||||
|
Application.get_env(:pleroma, :mrf_keyword, [])
|
||||||
|
|> Enum.map(fn {key, value} ->
|
||||||
|
{key,
|
||||||
|
Enum.map(value, fn
|
||||||
|
{pattern, replacement} ->
|
||||||
|
%{
|
||||||
|
"pattern" =>
|
||||||
|
if not is_binary(pattern) do
|
||||||
|
inspect(pattern)
|
||||||
|
else
|
||||||
|
pattern
|
||||||
|
end,
|
||||||
|
"replacement" => replacement
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern ->
|
||||||
|
if not is_binary(pattern) do
|
||||||
|
inspect(pattern)
|
||||||
|
else
|
||||||
|
pattern
|
||||||
|
end
|
||||||
|
end)}
|
||||||
|
end)
|
||||||
|
|> Enum.into(%{})
|
||||||
|
|
||||||
mrf_policies =
|
mrf_policies =
|
||||||
MRF.get_policies()
|
MRF.get_policies()
|
||||||
|> Enum.map(fn policy -> to_string(policy) |> String.split(".") |> List.last() end)
|
|> Enum.map(fn policy -> to_string(policy) |> String.split(".") |> List.last() end)
|
||||||
|
@ -66,13 +94,12 @@ def raw_nodeinfo() do
|
||||||
Config.get([:mrf_user_allowlist], [])
|
Config.get([:mrf_user_allowlist], [])
|
||||||
|> Enum.into(%{}, fn {k, v} -> {k, length(v)} end)
|
|> Enum.into(%{}, fn {k, v} -> {k, length(v)} end)
|
||||||
|
|
||||||
mrf_transparency = Keyword.get(instance, :mrf_transparency)
|
|
||||||
|
|
||||||
federation_response =
|
federation_response =
|
||||||
if mrf_transparency do
|
if Keyword.get(instance, :mrf_transparency) do
|
||||||
%{
|
%{
|
||||||
mrf_policies: mrf_policies,
|
mrf_policies: mrf_policies,
|
||||||
mrf_simple: mrf_simple,
|
mrf_simple: mrf_simple,
|
||||||
|
mrf_keyword: mrf_keyword,
|
||||||
mrf_user_allowlist: mrf_user_allowlist,
|
mrf_user_allowlist: mrf_user_allowlist,
|
||||||
quarantined_instances: quarantined
|
quarantined_instances: quarantined
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.OAuth.App do
|
defmodule Pleroma.Web.OAuth.App do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.{Changeset}
|
import Ecto.Changeset
|
||||||
|
|
||||||
schema "apps" do
|
schema "apps" do
|
||||||
field(:client_name, :string)
|
field(:client_name, :string)
|
||||||
|
|
|
@ -5,10 +5,13 @@
|
||||||
defmodule Pleroma.Web.OAuth.Authorization do
|
defmodule Pleroma.Web.OAuth.Authorization do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
alias Pleroma.{User, Repo}
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.OAuth.{Authorization, App}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Web.OAuth.Authorization
|
||||||
|
alias Pleroma.Web.OAuth.App
|
||||||
|
|
||||||
import Ecto.{Changeset, Query}
|
import Ecto.Changeset
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
schema "oauth_authorizations" do
|
schema "oauth_authorizations" do
|
||||||
field(:token, :string)
|
field(:token, :string)
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
defmodule Pleroma.Web.OAuth.OAuthController do
|
defmodule Pleroma.Web.OAuth.OAuthController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.Web.OAuth.{Authorization, Token, App}
|
alias Pleroma.Web.OAuth.Authorization
|
||||||
alias Pleroma.{Repo, User}
|
alias Pleroma.Web.OAuth.Token
|
||||||
|
alias Pleroma.Web.OAuth.App
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
alias Comeonin.Pbkdf2
|
alias Comeonin.Pbkdf2
|
||||||
|
|
||||||
plug(:fetch_session)
|
plug(:fetch_session)
|
||||||
|
@ -37,6 +40,7 @@ def create_authorization(conn, %{
|
||||||
true <- Pbkdf2.checkpw(password, user.password_hash),
|
true <- Pbkdf2.checkpw(password, user.password_hash),
|
||||||
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
|
{:auth_active, true} <- {:auth_active, User.auth_active?(user)},
|
||||||
%App{} = app <- Repo.get_by(App, client_id: client_id),
|
%App{} = app <- Repo.get_by(App, client_id: client_id),
|
||||||
|
true <- redirect_uri in String.split(app.redirect_uris),
|
||||||
{:ok, auth} <- Authorization.create_authorization(app, user) do
|
{:ok, auth} <- Authorization.create_authorization(app, user) do
|
||||||
# Special case: Local MastodonFE.
|
# Special case: Local MastodonFE.
|
||||||
redirect_uri =
|
redirect_uri =
|
||||||
|
|
|
@ -7,8 +7,11 @@ defmodule Pleroma.Web.OAuth.Token do
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias Pleroma.{User, Repo}
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.OAuth.{Token, App, Authorization}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Web.OAuth.Token
|
||||||
|
alias Pleroma.Web.OAuth.App
|
||||||
|
alias Pleroma.Web.OAuth.Authorization
|
||||||
|
|
||||||
schema "oauth_tokens" do
|
schema "oauth_tokens" do
|
||||||
field(:token, :string)
|
field(:token, :string)
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
defmodule Pleroma.Web.OStatus.ActivityRepresenter do
|
||||||
alias Pleroma.{Activity, User, Object}
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.OStatus.UserRepresenter
|
alias Pleroma.Web.OStatus.UserRepresenter
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
defp get_href(id) do
|
defp get_href(id) do
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.OStatus.FeedRepresenter do
|
defmodule Pleroma.Web.OStatus.FeedRepresenter do
|
||||||
alias Pleroma.Web.OStatus
|
|
||||||
alias Pleroma.Web.OStatus.{UserRepresenter, ActivityRepresenter}
|
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
|
alias Pleroma.Web.OStatus.ActivityRepresenter
|
||||||
|
alias Pleroma.Web.OStatus.UserRepresenter
|
||||||
|
|
||||||
def to_simple_form(user, activities, _users) do
|
def to_simple_form(user, activities, _users) do
|
||||||
most_recent_update =
|
most_recent_update =
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.OStatus.FollowHandler do
|
defmodule Pleroma.Web.OStatus.FollowHandler do
|
||||||
alias Pleroma.Web.{XML, OStatus}
|
alias Pleroma.Web.XML
|
||||||
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.OStatus.NoteHandler do
|
defmodule Pleroma.Web.OStatus.NoteHandler do
|
||||||
require Logger
|
require Logger
|
||||||
alias Pleroma.Web.{XML, OStatus}
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.{Object, Activity}
|
alias Pleroma.Web.XML
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.OStatus.UnfollowHandler do
|
defmodule Pleroma.Web.OStatus.UnfollowHandler do
|
||||||
alias Pleroma.Web.{XML, OStatus}
|
alias Pleroma.Web.XML
|
||||||
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,19 @@ defmodule Pleroma.Web.OStatus do
|
||||||
import Pleroma.Web.XML
|
import Pleroma.Web.XML
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
alias Pleroma.{Repo, User, Web, Object, Activity}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.{WebFinger, Websub}
|
|
||||||
alias Pleroma.Web.OStatus.{FollowHandler, UnfollowHandler, NoteHandler, DeleteHandler}
|
|
||||||
alias Pleroma.Web.ActivityPub.Transmogrifier
|
alias Pleroma.Web.ActivityPub.Transmogrifier
|
||||||
|
alias Pleroma.Web.WebFinger
|
||||||
|
alias Pleroma.Web.Websub
|
||||||
|
alias Pleroma.Web.OStatus.FollowHandler
|
||||||
|
alias Pleroma.Web.OStatus.UnfollowHandler
|
||||||
|
alias Pleroma.Web.OStatus.NoteHandler
|
||||||
|
alias Pleroma.Web.OStatus.DeleteHandler
|
||||||
|
|
||||||
def is_representable?(%Activity{data: data}) do
|
def is_representable?(%Activity{data: data}) do
|
||||||
object = Object.normalize(data["object"])
|
object = Object.normalize(data["object"])
|
||||||
|
|
|
@ -5,13 +5,17 @@
|
||||||
defmodule Pleroma.Web.OStatus.OStatusController do
|
defmodule Pleroma.Web.OStatus.OStatusController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.{User, Activity, Object}
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Web.OStatus.{FeedRepresenter, ActivityRepresenter}
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.{OStatus, Federator}
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.XML
|
|
||||||
alias Pleroma.Web.ActivityPub.ObjectView
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPubController
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.ActivityPub.ActivityPubController
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectView
|
||||||
|
alias Pleroma.Web.OStatus.ActivityRepresenter
|
||||||
|
alias Pleroma.Web.OStatus.FeedRepresenter
|
||||||
|
alias Pleroma.Web.Federator
|
||||||
|
alias Pleroma.Web.OStatus
|
||||||
|
alias Pleroma.Web.XML
|
||||||
|
|
||||||
plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming])
|
plug(Pleroma.Web.FederatingPlug when action in [:salmon_incoming])
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
defmodule Pleroma.Web.Push do
|
defmodule Pleroma.Web.Push do
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
alias Pleroma.{Repo, User}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.Push.Subscription
|
alias Pleroma.Web.Push.Subscription
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
|
@ -4,8 +4,11 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Push.Subscription do
|
defmodule Pleroma.Web.Push.Subscription do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
alias Pleroma.{Repo, User}
|
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.OAuth.Token
|
alias Pleroma.Web.OAuth.Token
|
||||||
alias Pleroma.Web.Push.Subscription
|
alias Pleroma.Web.Push.Subscription
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.RichMedia.Helpers do
|
defmodule Pleroma.Web.RichMedia.Helpers do
|
||||||
alias Pleroma.{Activity, Object, HTML}
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.HTML
|
||||||
alias Pleroma.Web.RichMedia.Parser
|
alias Pleroma.Web.RichMedia.Parser
|
||||||
|
|
||||||
def fetch_data_for_activity(%Activity{} = activity) do
|
def fetch_data_for_activity(%Activity{} = activity) do
|
||||||
|
|
|
@ -6,10 +6,12 @@ defmodule Pleroma.Web.Salmon do
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
|
|
||||||
use Bitwise
|
use Bitwise
|
||||||
|
|
||||||
alias Pleroma.Instances
|
alias Pleroma.Instances
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.XML
|
alias Pleroma.Web.XML
|
||||||
alias Pleroma.Web.OStatus.ActivityRepresenter
|
alias Pleroma.Web.OStatus.ActivityRepresenter
|
||||||
alias Pleroma.User
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
def decode(salmon) do
|
def decode(salmon) do
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
defmodule Pleroma.Web.Streamer do
|
defmodule Pleroma.Web.Streamer do
|
||||||
use GenServer
|
use GenServer
|
||||||
require Logger
|
require Logger
|
||||||
alias Pleroma.{User, Notification, Activity, Object, Repo}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Notification
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
|
||||||
@keepalive_interval :timer.seconds(30)
|
@keepalive_interval :timer.seconds(30)
|
||||||
|
|
|
@ -4,14 +4,19 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.UtilController do
|
defmodule Pleroma.Web.TwitterAPI.UtilController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
alias Comeonin.Pbkdf2
|
||||||
|
alias Pleroma.Emoji
|
||||||
|
alias Pleroma.PasswordResetToken
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.OStatus
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.WebFinger
|
alias Pleroma.Web.WebFinger
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
alias Comeonin.Pbkdf2
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.{Repo, PasswordResetToken, User, Emoji}
|
|
||||||
|
|
||||||
def show_password_reset(conn, %{"token" => token}) do
|
def show_password_reset(conn, %{"token" => token}) do
|
||||||
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
|
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
|
||||||
|
|
|
@ -2,16 +2,20 @@
|
||||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
# FIXME: Remove this module?
|
||||||
# THIS MODULE IS DEPRECATED! DON'T USE IT!
|
# THIS MODULE IS DEPRECATED! DON'T USE IT!
|
||||||
# USE THE Pleroma.Web.TwitterAPI.Views.ActivityView MODULE!
|
# USE THE Pleroma.Web.TwitterAPI.Views.ActivityView MODULE!
|
||||||
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
|
defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
|
||||||
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
|
use Pleroma.Web.TwitterAPI.Representers.BaseRepresenter
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
|
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
|
||||||
alias Pleroma.{Activity, User}
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView}
|
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.TwitterAPI.ActivityView
|
||||||
|
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||||
|
alias Pleroma.Web.TwitterAPI.UserView
|
||||||
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
alias Pleroma.Web.MastodonAPI.StatusView
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
|
|
||||||
defp user_by_ap_id(user_list, ap_id) do
|
defp user_by_ap_id(user_list, ap_id) do
|
||||||
|
|
|
@ -3,8 +3,13 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
|
||||||
alias Pleroma.{UserInviteToken, User, Activity, Repo, Object}
|
alias Pleroma.UserInviteToken
|
||||||
alias Pleroma.{UserEmail, Mailer}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.UserEmail
|
||||||
|
alias Pleroma.Mailer
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.TwitterAPI.UserView
|
alias Pleroma.Web.TwitterAPI.UserView
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
|
@ -305,16 +310,8 @@ def context_to_conversation_id(context) do
|
||||||
else
|
else
|
||||||
_e ->
|
_e ->
|
||||||
changeset = Object.context_mapping(context)
|
changeset = Object.context_mapping(context)
|
||||||
|
{:ok, object} = Object.insert_or_get(changeset)
|
||||||
case Repo.insert(changeset) do
|
object.id
|
||||||
{:ok, %{id: id}} ->
|
|
||||||
id
|
|
||||||
|
|
||||||
# This should be solved by an upsert, but it seems ecto
|
|
||||||
# has problems accessing the constraint inside the jsonb.
|
|
||||||
{:error, _} ->
|
|
||||||
Object.get_cached_by_ap_id(context).id
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,19 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
|
||||||
|
|
||||||
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
import Pleroma.Web.ControllerHelper, only: [json_response: 3]
|
||||||
|
|
||||||
alias Pleroma.Web.TwitterAPI.{TwitterAPI, UserView, ActivityView, NotificationView}
|
alias Ecto.Changeset
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
alias Pleroma.{Repo, Activity, Object, User, Notification}
|
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Ecto.Changeset
|
alias Pleroma.Web.CommonAPI
|
||||||
|
alias Pleroma.Web.TwitterAPI.ActivityView
|
||||||
|
alias Pleroma.Web.TwitterAPI.NotificationView
|
||||||
|
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||||
|
alias Pleroma.Web.TwitterAPI.UserView
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Object
|
||||||
|
alias Pleroma.Notification
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@ -24,7 +31,7 @@ def verify_credentials(%{assigns: %{user: user}} = conn, _params) do
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(UserView)
|
|> put_view(UserView)
|
||||||
|> render("show.json", %{user: user, token: token})
|
|> render("show.json", %{user: user, token: token, for: user})
|
||||||
end
|
end
|
||||||
|
|
||||||
def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do
|
def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do
|
||||||
|
@ -523,7 +530,7 @@ def friends(%{assigns: %{user: for_user}} = conn, params) do
|
||||||
friends =
|
friends =
|
||||||
cond do
|
cond do
|
||||||
for_user && user.id == for_user.id -> friends
|
for_user && user.id == for_user.id -> friends
|
||||||
user.info.hide_followings -> []
|
user.info.hide_follows -> []
|
||||||
true -> friends
|
true -> friends
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -618,7 +625,7 @@ def raw_empty_array(conn, _params) do
|
||||||
|
|
||||||
defp build_info_cng(user, params) do
|
defp build_info_cng(user, params) do
|
||||||
info_params =
|
info_params =
|
||||||
["no_rich_text", "locked", "hide_followers", "hide_followings"]
|
["no_rich_text", "locked", "hide_followers", "hide_follows", "show_role"]
|
||||||
|> Enum.reduce(%{}, fn key, res ->
|
|> Enum.reduce(%{}, fn key, res ->
|
||||||
if value = params[key] do
|
if value = params[key] do
|
||||||
Map.put(res, key, value == "true")
|
Map.put(res, key, value == "true")
|
||||||
|
|
|
@ -4,19 +4,18 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.ActivityView do
|
defmodule Pleroma.Web.TwitterAPI.ActivityView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Web.TwitterAPI.UserView
|
|
||||||
alias Pleroma.Web.TwitterAPI.ActivityView
|
|
||||||
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
|
||||||
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
|
|
||||||
alias Pleroma.Web.MastodonAPI.StatusView
|
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
|
alias Pleroma.Web.TwitterAPI.ActivityView
|
||||||
|
alias Pleroma.Web.TwitterAPI.TwitterAPI
|
||||||
|
alias Pleroma.Web.TwitterAPI.UserView
|
||||||
|
alias Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
require Logger
|
require Logger
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.NotificationView do
|
defmodule Pleroma.Web.TwitterAPI.NotificationView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.{Notification, User}
|
alias Pleroma.Notification
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
alias Pleroma.Web.TwitterAPI.UserView
|
|
||||||
alias Pleroma.Web.TwitterAPI.ActivityView
|
alias Pleroma.Web.TwitterAPI.ActivityView
|
||||||
|
alias Pleroma.Web.TwitterAPI.UserView
|
||||||
|
|
||||||
defp get_user(ap_id, opts) do
|
defp get_user(ap_id, opts) do
|
||||||
cond do
|
cond do
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.TwitterAPI.UserView do
|
defmodule Pleroma.Web.TwitterAPI.UserView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
|
alias Pleroma.HTML
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
alias Pleroma.HTML
|
|
||||||
|
|
||||||
def render("show.json", %{user: user = %User{}} = assigns) do
|
def render("show.json", %{user: user = %User{}} = assigns) do
|
||||||
render_one(user, Pleroma.Web.TwitterAPI.UserView, "user.json", assigns)
|
render_one(user, Pleroma.Web.TwitterAPI.UserView, "user.json", assigns)
|
||||||
|
@ -109,7 +109,7 @@ defp do_render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
"default_scope" => user.info.default_scope,
|
"default_scope" => user.info.default_scope,
|
||||||
"no_rich_text" => user.info.no_rich_text,
|
"no_rich_text" => user.info.no_rich_text,
|
||||||
"hide_followers" => user.info.hide_followers,
|
"hide_followers" => user.info.hide_followers,
|
||||||
"hide_followings" => user.info.hide_followings,
|
"hide_follows" => user.info.hide_follows,
|
||||||
"fields" => fields,
|
"fields" => fields,
|
||||||
|
|
||||||
# Pleroma extension
|
# Pleroma extension
|
||||||
|
@ -119,6 +119,12 @@ defp do_render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data =
|
||||||
|
if(user.info.is_admin || user.info.is_moderator,
|
||||||
|
do: maybe_with_role(data, user, for_user),
|
||||||
|
else: data
|
||||||
|
)
|
||||||
|
|
||||||
if assigns[:token] do
|
if assigns[:token] do
|
||||||
Map.put(data, "token", token_string(assigns[:token]))
|
Map.put(data, "token", token_string(assigns[:token]))
|
||||||
else
|
else
|
||||||
|
@ -126,6 +132,20 @@ defp do_render("user.json", %{user: user = %User{}} = assigns) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp maybe_with_role(data, %User{id: id} = user, %User{id: id}) do
|
||||||
|
Map.merge(data, %{"role" => role(user), "show_role" => user.info.show_role})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_with_role(data, %User{info: %{show_role: true}} = user, _user) do
|
||||||
|
Map.merge(data, %{"role" => role(user)})
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_with_role(data, _, _), do: data
|
||||||
|
|
||||||
|
defp role(%User{info: %{:is_admin => true}}), do: "admin"
|
||||||
|
defp role(%User{info: %{:is_moderator => true}}), do: "moderator"
|
||||||
|
defp role(_), do: "member"
|
||||||
|
|
||||||
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
|
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
|
||||||
defp image_url(_), do: nil
|
defp image_url(_), do: nil
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ defmodule Pleroma.Web.UploaderController do
|
||||||
|
|
||||||
alias Pleroma.Uploaders.Uploader
|
alias Pleroma.Uploaders.Uploader
|
||||||
|
|
||||||
def callback(conn, params = %{"upload_path" => upload_path}) do
|
def callback(conn, %{"upload_path" => upload_path} = params) do
|
||||||
process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
|
process_callback(conn, :global.whereis_name({Uploader, upload_path}), params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@ def controller do
|
||||||
quote do
|
quote do
|
||||||
use Phoenix.Controller, namespace: Pleroma.Web
|
use Phoenix.Controller, namespace: Pleroma.Web
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Pleroma.Web.{Gettext, Router.Helpers}
|
import Pleroma.Web.Gettext
|
||||||
|
import Pleroma.Web.Router.Helpers
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,7 +38,9 @@ def view do
|
||||||
# Import convenience functions from controllers
|
# Import convenience functions from controllers
|
||||||
import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
|
import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
|
||||||
|
|
||||||
import Pleroma.Web.{ErrorHelpers, Gettext, Router.Helpers}
|
import Pleroma.Web.ErrorHelpers
|
||||||
|
import Pleroma.Web.Gettext
|
||||||
|
import Pleroma.Web.Router.Helpers
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@ -71,6 +74,7 @@ def safe_render_many(collection, view, template, assigns \\ %{}) do
|
||||||
def router do
|
def router do
|
||||||
quote do
|
quote do
|
||||||
use Phoenix.Router
|
use Phoenix.Router
|
||||||
|
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
import Phoenix.Controller
|
import Phoenix.Controller
|
||||||
end
|
end
|
||||||
|
@ -78,6 +82,7 @@ def router do
|
||||||
|
|
||||||
def channel do
|
def channel do
|
||||||
quote do
|
quote do
|
||||||
|
# credo:disable-for-next-line Credo.Check.Consistency.MultiAliasImportRequireUse
|
||||||
use Phoenix.Channel
|
use Phoenix.Channel
|
||||||
import Pleroma.Web.Gettext
|
import Pleroma.Web.Gettext
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
defmodule Pleroma.Web.WebFinger do
|
defmodule Pleroma.Web.WebFinger do
|
||||||
@httpoison Application.get_env(:pleroma, :httpoison)
|
@httpoison Application.get_env(:pleroma, :httpoison)
|
||||||
|
|
||||||
alias Pleroma.{User, XmlBuilder}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.XmlBuilder
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.{XML, Salmon, OStatus}
|
alias Pleroma.Web.XML
|
||||||
|
alias Pleroma.Web.Salmon
|
||||||
|
alias Pleroma.Web.OStatus
|
||||||
require Jason
|
require Jason
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,16 @@
|
||||||
|
|
||||||
defmodule Pleroma.Web.Websub do
|
defmodule Pleroma.Web.Websub do
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
alias Pleroma.Repo
|
|
||||||
alias Pleroma.Instances
|
alias Pleroma.Instances
|
||||||
alias Pleroma.Web.Websub.{WebsubServerSubscription, WebsubClientSubscription}
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.Web.Websub.WebsubServerSubscription
|
||||||
|
alias Pleroma.Web.Websub.WebsubClientSubscription
|
||||||
alias Pleroma.Web.OStatus.FeedRepresenter
|
alias Pleroma.Web.OStatus.FeedRepresenter
|
||||||
alias Pleroma.Web.{XML, Endpoint, OStatus, Federator}
|
alias Pleroma.Web.XML
|
||||||
|
alias Pleroma.Web.Endpoint
|
||||||
|
alias Pleroma.Web.OStatus
|
||||||
alias Pleroma.Web.Router.Helpers
|
alias Pleroma.Web.Router.Helpers
|
||||||
|
alias Pleroma.Web.Federator
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
defmodule Pleroma.Web.Websub.WebsubController do
|
defmodule Pleroma.Web.Websub.WebsubController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.{Repo, User}
|
alias Pleroma.Repo
|
||||||
alias Pleroma.Web.{Websub, Federator}
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.Websub
|
||||||
|
alias Pleroma.Web.Federator
|
||||||
alias Pleroma.Web.Websub.WebsubClientSubscription
|
alias Pleroma.Web.Websub.WebsubClientSubscription
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
|
@ -2,9 +2,9 @@ defmodule Pleroma.Repo.Migrations.SplitHideNetwork do
|
||||||
use Ecto.Migration
|
use Ecto.Migration
|
||||||
|
|
||||||
def up do
|
def up do
|
||||||
execute("UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network')")
|
execute("UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network') AND local")
|
||||||
execute("UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network')")
|
execute("UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network') WHERE local")
|
||||||
execute("UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network')")
|
execute("UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network') WHERE local")
|
||||||
end
|
end
|
||||||
|
|
||||||
def down do
|
def down do
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.6aa5664a1a2c0832ce7b.js></script><script type=text/javascript src=/static/js/vendor.56a115a1d7339d6811a0.js></script><script type=text/javascript src=/static/js/app.59ebcfb47f86a7a5ba3f.js></script></body></html>
|
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.d75cda10f04aeefec7b657f8244070e9.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.f00ab54db04706aab2c9.js></script><script type=text/javascript src=/static/js/vendor.5173dfeead1ded3d1f46.js></script><script type=text/javascript src=/static/js/app.0e4952ec8d775da840f1.js></script></body></html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue