@@ -0,0 +1,395 @@ | |||
Attribution 4.0 International | |||
======================================================================= | |||
Creative Commons Corporation ("Creative Commons") is not a law firm and | |||
does not provide legal services or legal advice. Distribution of | |||
Creative Commons public licenses does not create a lawyer-client or | |||
other relationship. Creative Commons makes its licenses and related | |||
information available on an "as-is" basis. Creative Commons gives no | |||
warranties regarding its licenses, any material licensed under their | |||
terms and conditions, or any related information. Creative Commons | |||
disclaims all liability for damages resulting from their use to the | |||
fullest extent possible. | |||
Using Creative Commons Public Licenses | |||
Creative Commons public licenses provide a standard set of terms and | |||
conditions that creators and other rights holders may use to share | |||
original works of authorship and other material subject to copyright | |||
and certain other rights specified in the public license below. The | |||
following considerations are for informational purposes only, are not | |||
exhaustive, and do not form part of our licenses. | |||
Considerations for licensors: Our public licenses are | |||
intended for use by those authorized to give the public | |||
permission to use material in ways otherwise restricted by | |||
copyright and certain other rights. Our licenses are | |||
irrevocable. Licensors should read and understand the terms | |||
and conditions of the license they choose before applying it. | |||
Licensors should also secure all rights necessary before | |||
applying our licenses so that the public can reuse the | |||
material as expected. Licensors should clearly mark any | |||
material not subject to the license. This includes other CC- | |||
licensed material, or material used under an exception or | |||
limitation to copyright. More considerations for licensors: | |||
wiki.creativecommons.org/Considerations_for_licensors | |||
Considerations for the public: By using one of our public | |||
licenses, a licensor grants the public permission to use the | |||
licensed material under specified terms and conditions. If | |||
the licensor's permission is not necessary for any reason--for | |||
example, because of any applicable exception or limitation to | |||
copyright--then that use is not regulated by the license. Our | |||
licenses grant only permissions under copyright and certain | |||
other rights that a licensor has authority to grant. Use of | |||
the licensed material may still be restricted for other | |||
reasons, including because others have copyright or other | |||
rights in the material. A licensor may make special requests, | |||
such as asking that all changes be marked or described. | |||
Although not required by our licenses, you are encouraged to | |||
respect those requests where reasonable. More considerations | |||
for the public: | |||
wiki.creativecommons.org/Considerations_for_licensees | |||
======================================================================= | |||
Creative Commons Attribution 4.0 International Public License | |||
By exercising the Licensed Rights (defined below), You accept and agree | |||
to be bound by the terms and conditions of this Creative Commons | |||
Attribution 4.0 International Public License ("Public License"). To the | |||
extent this Public License may be interpreted as a contract, You are | |||
granted the Licensed Rights in consideration of Your acceptance of | |||
these terms and conditions, and the Licensor grants You such rights in | |||
consideration of benefits the Licensor receives from making the | |||
Licensed Material available under these terms and conditions. | |||
Section 1 -- Definitions. | |||
a. Adapted Material means material subject to Copyright and Similar | |||
Rights that is derived from or based upon the Licensed Material | |||
and in which the Licensed Material is translated, altered, | |||
arranged, transformed, or otherwise modified in a manner requiring | |||
permission under the Copyright and Similar Rights held by the | |||
Licensor. For purposes of this Public License, where the Licensed | |||
Material is a musical work, performance, or sound recording, | |||
Adapted Material is always produced where the Licensed Material is | |||
synched in timed relation with a moving image. | |||
b. Adapter's License means the license You apply to Your Copyright | |||
and Similar Rights in Your contributions to Adapted Material in | |||
accordance with the terms and conditions of this Public License. | |||
c. Copyright and Similar Rights means copyright and/or similar rights | |||
closely related to copyright including, without limitation, | |||
performance, broadcast, sound recording, and Sui Generis Database | |||
Rights, without regard to how the rights are labeled or | |||
categorized. For purposes of this Public License, the rights | |||
specified in Section 2(b)(1)-(2) are not Copyright and Similar | |||
Rights. | |||
d. Effective Technological Measures means those measures that, in the | |||
absence of proper authority, may not be circumvented under laws | |||
fulfilling obligations under Article 11 of the WIPO Copyright | |||
Treaty adopted on December 20, 1996, and/or similar international | |||
agreements. | |||
e. Exceptions and Limitations means fair use, fair dealing, and/or | |||
any other exception or limitation to Copyright and Similar Rights | |||
that applies to Your use of the Licensed Material. | |||
f. Licensed Material means the artistic or literary work, database, | |||
or other material to which the Licensor applied this Public | |||
License. | |||
g. Licensed Rights means the rights granted to You subject to the | |||
terms and conditions of this Public License, which are limited to | |||
all Copyright and Similar Rights that apply to Your use of the | |||
Licensed Material and that the Licensor has authority to license. | |||
h. Licensor means the individual(s) or entity(ies) granting rights | |||
under this Public License. | |||
i. Share means to provide material to the public by any means or | |||
process that requires permission under the Licensed Rights, such | |||
as reproduction, public display, public performance, distribution, | |||
dissemination, communication, or importation, and to make material | |||
available to the public including in ways that members of the | |||
public may access the material from a place and at a time | |||
individually chosen by them. | |||
j. Sui Generis Database Rights means rights other than copyright | |||
resulting from Directive 96/9/EC of the European Parliament and of | |||
the Council of 11 March 1996 on the legal protection of databases, | |||
as amended and/or succeeded, as well as other essentially | |||
equivalent rights anywhere in the world. | |||
k. You means the individual or entity exercising the Licensed Rights | |||
under this Public License. Your has a corresponding meaning. | |||
Section 2 -- Scope. | |||
a. License grant. | |||
1. Subject to the terms and conditions of this Public License, | |||
the Licensor hereby grants You a worldwide, royalty-free, | |||
non-sublicensable, non-exclusive, irrevocable license to | |||
exercise the Licensed Rights in the Licensed Material to: | |||
a. reproduce and Share the Licensed Material, in whole or | |||
in part; and | |||
b. produce, reproduce, and Share Adapted Material. | |||
2. Exceptions and Limitations. For the avoidance of doubt, where | |||
Exceptions and Limitations apply to Your use, this Public | |||
License does not apply, and You do not need to comply with | |||
its terms and conditions. | |||
3. Term. The term of this Public License is specified in Section | |||
6(a). | |||
4. Media and formats; technical modifications allowed. The | |||
Licensor authorizes You to exercise the Licensed Rights in | |||
all media and formats whether now known or hereafter created, | |||
and to make technical modifications necessary to do so. The | |||
Licensor waives and/or agrees not to assert any right or | |||
authority to forbid You from making technical modifications | |||
necessary to exercise the Licensed Rights, including | |||
technical modifications necessary to circumvent Effective | |||
Technological Measures. For purposes of this Public License, | |||
simply making modifications authorized by this Section 2(a) | |||
(4) never produces Adapted Material. | |||
5. Downstream recipients. | |||
a. Offer from the Licensor -- Licensed Material. Every | |||
recipient of the Licensed Material automatically | |||
receives an offer from the Licensor to exercise the | |||
Licensed Rights under the terms and conditions of this | |||
Public License. | |||
b. No downstream restrictions. You may not offer or impose | |||
any additional or different terms or conditions on, or | |||
apply any Effective Technological Measures to, the | |||
Licensed Material if doing so restricts exercise of the | |||
Licensed Rights by any recipient of the Licensed | |||
Material. | |||
6. No endorsement. Nothing in this Public License constitutes or | |||
may be construed as permission to assert or imply that You | |||
are, or that Your use of the Licensed Material is, connected | |||
with, or sponsored, endorsed, or granted official status by, | |||
the Licensor or others designated to receive attribution as | |||
provided in Section 3(a)(1)(A)(i). | |||
b. Other rights. | |||
1. Moral rights, such as the right of integrity, are not | |||
licensed under this Public License, nor are publicity, | |||
privacy, and/or other similar personality rights; however, to | |||
the extent possible, the Licensor waives and/or agrees not to | |||
assert any such rights held by the Licensor to the limited | |||
extent necessary to allow You to exercise the Licensed | |||
Rights, but not otherwise. | |||
2. Patent and trademark rights are not licensed under this | |||
Public License. | |||
3. To the extent possible, the Licensor waives any right to | |||
collect royalties from You for the exercise of the Licensed | |||
Rights, whether directly or through a collecting society | |||
under any voluntary or waivable statutory or compulsory | |||
licensing scheme. In all other cases the Licensor expressly | |||
reserves any right to collect such royalties. | |||
Section 3 -- License Conditions. | |||
Your exercise of the Licensed Rights is expressly made subject to the | |||
following conditions. | |||
a. Attribution. | |||
1. If You Share the Licensed Material (including in modified | |||
form), You must: | |||
a. retain the following if it is supplied by the Licensor | |||
with the Licensed Material: | |||
i. identification of the creator(s) of the Licensed | |||
Material and any others designated to receive | |||
attribution, in any reasonable manner requested by | |||
the Licensor (including by pseudonym if | |||
designated); | |||
ii. a copyright notice; | |||
iii. a notice that refers to this Public License; | |||
iv. a notice that refers to the disclaimer of | |||
warranties; | |||
v. a URI or hyperlink to the Licensed Material to the | |||
extent reasonably practicable; | |||
b. indicate if You modified the Licensed Material and | |||
retain an indication of any previous modifications; and | |||
c. indicate the Licensed Material is licensed under this | |||
Public License, and include the text of, or the URI or | |||
hyperlink to, this Public License. | |||
2. You may satisfy the conditions in Section 3(a)(1) in any | |||
reasonable manner based on the medium, means, and context in | |||
which You Share the Licensed Material. For example, it may be | |||
reasonable to satisfy the conditions by providing a URI or | |||
hyperlink to a resource that includes the required | |||
information. | |||
3. If requested by the Licensor, You must remove any of the | |||
information required by Section 3(a)(1)(A) to the extent | |||
reasonably practicable. | |||
4. If You Share Adapted Material You produce, the Adapter's | |||
License You apply must not prevent recipients of the Adapted | |||
Material from complying with this Public License. | |||
Section 4 -- Sui Generis Database Rights. | |||
Where the Licensed Rights include Sui Generis Database Rights that | |||
apply to Your use of the Licensed Material: | |||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right | |||
to extract, reuse, reproduce, and Share all or a substantial | |||
portion of the contents of the database; | |||
b. if You include all or a substantial portion of the database | |||
contents in a database in which You have Sui Generis Database | |||
Rights, then the database in which You have Sui Generis Database | |||
Rights (but not its individual contents) is Adapted Material; and | |||
c. You must comply with the conditions in Section 3(a) if You Share | |||
all or a substantial portion of the contents of the database. | |||
For the avoidance of doubt, this Section 4 supplements and does not | |||
replace Your obligations under this Public License where the Licensed | |||
Rights include other Copyright and Similar Rights. | |||
Section 5 -- Disclaimer of Warranties and Limitation of Liability. | |||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE | |||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS | |||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF | |||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, | |||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, | |||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR | |||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, | |||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT | |||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT | |||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. | |||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE | |||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, | |||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, | |||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, | |||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR | |||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN | |||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR | |||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR | |||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. | |||
c. The disclaimer of warranties and limitation of liability provided | |||
above shall be interpreted in a manner that, to the extent | |||
possible, most closely approximates an absolute disclaimer and | |||
waiver of all liability. | |||
Section 6 -- Term and Termination. | |||
a. This Public License applies for the term of the Copyright and | |||
Similar Rights licensed here. However, if You fail to comply with | |||
this Public License, then Your rights under this Public License | |||
terminate automatically. | |||
b. Where Your right to use the Licensed Material has terminated under | |||
Section 6(a), it reinstates: | |||
1. automatically as of the date the violation is cured, provided | |||
it is cured within 30 days of Your discovery of the | |||
violation; or | |||
2. upon express reinstatement by the Licensor. | |||
For the avoidance of doubt, this Section 6(b) does not affect any | |||
right the Licensor may have to seek remedies for Your violations | |||
of this Public License. | |||
c. For the avoidance of doubt, the Licensor may also offer the | |||
Licensed Material under separate terms or conditions or stop | |||
distributing the Licensed Material at any time; however, doing so | |||
will not terminate this Public License. | |||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public | |||
License. | |||
Section 7 -- Other Terms and Conditions. | |||
a. The Licensor shall not be bound by any additional or different | |||
terms or conditions communicated by You unless expressly agreed. | |||
b. Any arrangements, understandings, or agreements regarding the | |||
Licensed Material not stated herein are separate from and | |||
independent of the terms and conditions of this Public License. | |||
Section 8 -- Interpretation. | |||
a. For the avoidance of doubt, this Public License does not, and | |||
shall not be interpreted to, reduce, limit, restrict, or impose | |||
conditions on any use of the Licensed Material that could lawfully | |||
be made without permission under this Public License. | |||
b. To the extent possible, if any provision of this Public License is | |||
deemed unenforceable, it shall be automatically reformed to the | |||
minimum extent necessary to make it enforceable. If the provision | |||
cannot be reformed, it shall be severed from this Public License | |||
without affecting the enforceability of the remaining terms and | |||
conditions. | |||
c. No term or condition of this Public License will be waived and no | |||
failure to comply consented to unless expressly agreed to by the | |||
Licensor. | |||
d. Nothing in this Public License constitutes or may be interpreted | |||
as a limitation upon, or waiver of, any privileges and immunities | |||
that apply to the Licensor or You, including from the legal | |||
processes of any jurisdiction or authority. | |||
======================================================================= | |||
Creative Commons is not a party to its public | |||
licenses. Notwithstanding, Creative Commons may elect to apply one of | |||
its public licenses to material it publishes and in those instances | |||
will be considered the “Licensor.” The text of the Creative Commons | |||
public licenses is dedicated to the public domain under the CC0 Public | |||
Domain Dedication. Except for the limited purpose of indicating that | |||
material is shared under a Creative Commons public license or as | |||
otherwise permitted by the Creative Commons policies published at | |||
creativecommons.org/policies, Creative Commons does not authorize the | |||
use of the trademark "Creative Commons" or any other trademark or logo | |||
of Creative Commons without its prior written consent including, | |||
without limitation, in connection with any unauthorized modifications | |||
to any of its public licenses or any other arrangements, | |||
understandings, or agreements concerning use of licensed material. For | |||
the avoidance of doubt, this paragraph does not form part of the | |||
public licenses. | |||
Creative Commons may be contacted at creativecommons.org. |
@@ -3,16 +3,41 @@ All notable changes to this project will be documented in this file. | |||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
## unreleased-patch - ??? | |||
## Unreleased | |||
### Changed | |||
- Renamed `:await_up_timeout` in `:connections_pool` namespace to `:connect_timeout`, old name is deprecated. | |||
- Renamed `:timeout` in `pools` namespace to `:recv_timeout`, old name is deprecated. | |||
### Removed | |||
- **Breaking:** Removed `Pleroma.Workers.Cron.StatsWorker` setting from Oban `:crontab`. | |||
## [2.1.1] - 2020-09-08 | |||
### Security | |||
- Fix possible DoS in Mastodon API user search due to an error in match clauses, leading to an infinite recursion and subsequent OOM with certain inputs. | |||
- Fix metadata leak for accounts and statuses on private instances. | |||
- Fix possible DoS in Admin API search using an atom leak vulnerability. Authentication with admin rights was required to exploit. | |||
### Changed | |||
- **Breaking:** The metadata providers RelMe and Feed are no longer configurable. RelMe should always be activated and Feed only provides a <link> header tag for the actual RSS/Atom feed when the instance is public. | |||
- Improved error message when cmake is not available at build stage. | |||
### Added | |||
- Rich media failure tracking (along with `:failure_backoff` option) | |||
- Rich media failure tracking (along with `:failure_backoff` option). | |||
### Fixed | |||
- Default HTTP adapter not respecting pool setting, leading to possible OOM. | |||
- Fixed uploading webp images when the Exiftool Upload Filter is enabled by skipping them | |||
- Mastodon API: Search parameter `following` now correctly returns the followings rather than the followers | |||
- Mastodon API: Timelines hanging for (`number of posts with links * rich media timeout`) in the worst case. | |||
Reduced to just rich media timeout. | |||
- Password resets no longer processed for deactivated accounts | |||
- Mastodon API: Cards being wrong for preview statuses due to cache key collision. | |||
- Password resets no longer processed for deactivated accounts. | |||
- Favicon scraper raising exceptions on URLs longer than 255 characters. | |||
## [2.1.0] - 2020-08-28 | |||
@@ -6,7 +6,7 @@ Currently, Pleroma offers bugfixes and security patches only for the latest mino | |||
| Version | Support | |||
|---------| -------- | |||
| 2.0 | Bugfixes and security patches | |||
| 2.1 | Bugfixes and security patches | |||
## Reporting a vulnerability | |||
@@ -463,9 +463,7 @@ config :pleroma, :gopher, | |||
config :pleroma, Pleroma.Web.Metadata, | |||
providers: [ | |||
Pleroma.Web.Metadata.Providers.OpenGraph, | |||
Pleroma.Web.Metadata.Providers.TwitterCard, | |||
Pleroma.Web.Metadata.Providers.RelMe, | |||
Pleroma.Web.Metadata.Providers.Feed | |||
Pleroma.Web.Metadata.Providers.TwitterCard | |||
], | |||
unfurl_nsfw: false | |||
@@ -555,7 +553,6 @@ config :pleroma, Oban, | |||
plugins: [Oban.Plugins.Pruner], | |||
crontab: [ | |||
{"0 0 * * *", Pleroma.Workers.Cron.ClearOauthTokenWorker}, | |||
{"0 * * * *", Pleroma.Workers.Cron.StatsWorker}, | |||
{"* * * * *", Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker}, | |||
{"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker}, | |||
{"0 0 * * *", Pleroma.Workers.Cron.NewUsersDigestWorker} | |||
@@ -681,7 +678,7 @@ config :pleroma, :static_fe, enabled: false | |||
# With no frontend configuration, the bundled files from the `static` directory will | |||
# be used. | |||
# | |||
# config :pleroma, :frontends, | |||
# config :pleroma, :frontends, | |||
# primary: %{"name" => "pleroma-fe", "ref" => "develop"}, | |||
# admin: %{"name" => "admin-fe", "ref" => "stable"}, | |||
# available: %{...} | |||
@@ -745,28 +742,28 @@ config :pleroma, :connections_pool, | |||
max_connections: 250, | |||
max_idle_time: 30_000, | |||
retry: 0, | |||
await_up_timeout: 5_000 | |||
connect_timeout: 5_000 | |||
config :pleroma, :pools, | |||
federation: [ | |||
size: 50, | |||
max_waiting: 10, | |||
timeout: 10_000 | |||
recv_timeout: 10_000 | |||
], | |||
media: [ | |||
size: 50, | |||
max_waiting: 20, | |||
timeout: 15_000 | |||
recv_timeout: 15_000 | |||
], | |||
upload: [ | |||
size: 25, | |||
max_waiting: 5, | |||
timeout: 15_000 | |||
recv_timeout: 15_000 | |||
], | |||
default: [ | |||
size: 10, | |||
max_waiting: 2, | |||
timeout: 5_000 | |||
recv_timeout: 5_000 | |||
] | |||
config :pleroma, :hackney_pools, | |||
@@ -2326,7 +2326,6 @@ config :pleroma, :config_description, [ | |||
description: "Settings for cron background jobs", | |||
suggestions: [ | |||
{"0 0 * * *", Pleroma.Workers.Cron.ClearOauthTokenWorker}, | |||
{"0 * * * *", Pleroma.Workers.Cron.StatsWorker}, | |||
{"* * * * *", Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker}, | |||
{"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker}, | |||
{"0 0 * * *", Pleroma.Workers.Cron.NewUsersDigestWorker} | |||
@@ -3413,7 +3412,7 @@ config :pleroma, :config_description, [ | |||
suggestions: [250] | |||
}, | |||
%{ | |||
key: :await_up_timeout, | |||
key: :connect_timeout, | |||
type: :integer, | |||
description: "Timeout while `gun` will wait until connection is up. Default: 5000ms.", | |||
suggestions: [5000] | |||
@@ -3451,6 +3450,12 @@ config :pleroma, :config_description, [ | |||
description: | |||
"Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made", | |||
suggestions: [10] | |||
}, | |||
%{ | |||
key: :recv_timeout, | |||
type: :integer, | |||
description: "Timeout for the pool while gun will wait for response", | |||
suggestions: [10_000] | |||
} | |||
] | |||
} | |||
@@ -114,8 +114,6 @@ config :pleroma, Pleroma.Plugs.RemoteIp, enabled: false | |||
config :pleroma, Pleroma.Web.ApiSpec.CastAndValidate, strict: true | |||
config :pleroma, :instances_favicons, enabled: true | |||
config :pleroma, Pleroma.Uploaders.S3, | |||
bucket: nil, | |||
streaming_enabled: true, | |||
@@ -115,6 +115,7 @@ To add configuration to your config file, you can copy it from the base config. | |||
* `Pleroma.Web.ActivityPub.MRF.VocabularyPolicy`: Restricts activities to a configured set of vocabulary. (See [`:mrf_vocabulary`](#mrf_vocabulary)). | |||
* `Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy`: Rejects or delists posts based on their age when received. (See [`:mrf_object_age`](#mrf_object_age)). | |||
* `Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy`: Sets a default expiration on all posts made by users of the local instance. Requires `Pleroma.ActivityExpiration` to be enabled for processing the scheduled delections. | |||
* `Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy`: Makes all bot posts to disappear from public timelines. | |||
* `transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo). | |||
* `transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value. | |||
@@ -352,8 +353,6 @@ config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http, | |||
* `providers`: a list of metadata providers to enable. Providers available: | |||
* `Pleroma.Web.Metadata.Providers.OpenGraph` | |||
* `Pleroma.Web.Metadata.Providers.TwitterCard` | |||
* `Pleroma.Web.Metadata.Providers.RelMe` - add links from user bio with rel=me into the `<header>` as `<link rel=me>`. | |||
* `Pleroma.Web.Metadata.Providers.Feed` - add a link to a user's Atom feed into the `<header>` as `<link rel=alternate>`. | |||
* `unfurl_nsfw`: If set to `true` nsfw attachments will be shown in previews. | |||
### :rich_media (consumer) | |||
@@ -498,7 +497,7 @@ Settings for HTTP connection pool. | |||
* `:connection_acquisition_wait` - Timeout to acquire a connection from pool.The total max time is this value multiplied by the number of retries. | |||
* `connection_acquisition_retries` - Number of attempts to acquire the connection from the pool if it is overloaded. Each attempt is timed `:connection_acquisition_wait` apart. | |||
* `:max_connections` - Maximum number of connections in the pool. | |||
* `:await_up_timeout` - Timeout to connect to the host. | |||
* `:connect_timeout` - Timeout to connect to the host. | |||
* `:reclaim_multiplier` - Multiplied by `:max_connections` this will be the maximum number of idle connections that will be reclaimed in case the pool is overloaded. | |||
### :pools | |||
@@ -517,7 +516,7 @@ There are four pools used: | |||
For each pool, the options are: | |||
* `:size` - limit to how much requests can be concurrently executed. | |||
* `:timeout` - timeout while `gun` will wait for response | |||
* `:recv_timeout` - timeout while `gun` will wait for response | |||
* `:max_waiting` - limit to how much requests can be waiting for others to finish, after this is reached, subsequent requests will be dropped. | |||
## Captcha | |||
@@ -18,6 +18,7 @@ defmodule Mix.Pleroma do | |||
@doc "Common functions to be reused in mix tasks" | |||
def start_pleroma do | |||
Pleroma.Config.Holder.save_default() | |||
Pleroma.Config.Oban.warn() | |||
Application.put_env(:phoenix, :serve_endpoints, false, persistent: true) | |||
if Pleroma.Config.get(:env) != :test do | |||
@@ -91,20 +91,17 @@ defmodule Mix.Tasks.Pleroma.Benchmark do | |||
"Without conn and without pool" => fn -> | |||
{:ok, %Tesla.Env{}} = | |||
Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], | |||
adapter: [pool: :no_pool, receive_conn: false] | |||
pool: :no_pool, | |||
receive_conn: false | |||
) | |||
end, | |||
"Without conn and with pool" => fn -> | |||
{:ok, %Tesla.Env{}} = | |||
Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], | |||
adapter: [receive_conn: false] | |||
) | |||
Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], receive_conn: false) | |||
end, | |||
"With reused conn and without pool" => fn -> | |||
{:ok, %Tesla.Env{}} = | |||
Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], | |||
adapter: [pool: :no_pool] | |||
) | |||
Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500", [], pool: :no_pool) | |||
end, | |||
"With reused conn and with pool" => fn -> | |||
{:ok, %Tesla.Env{}} = Pleroma.HTTP.get("https://httpbin.org/stream-bytes/1500") | |||
@@ -124,9 +124,7 @@ defmodule Mix.Tasks.Pleroma.Frontend do | |||
url = String.replace(frontend_info["build_url"], "${ref}", frontend_info["ref"]) | |||
with {:ok, %{status: 200, body: zip_body}} <- | |||
Pleroma.HTTP.get(url, [], | |||
adapter: [pool: :media, timeout: 120_000, recv_timeout: 120_000] | |||
) do | |||
Pleroma.HTTP.get(url, [], pool: :media, recv_timeout: 120_000) do | |||
unzip(zip_body, dest) | |||
else | |||
e -> {:error, e} | |||
@@ -50,6 +50,7 @@ defmodule Pleroma.Application do | |||
Pleroma.Telemetry.Logger.attach() | |||
Config.Holder.save_default() | |||
Pleroma.HTML.compile_scrubbers() | |||
Pleroma.Config.Oban.warn() | |||
Config.DeprecationWarnings.warn() | |||
Pleroma.Plugs.HTTPSecurityPlug.warn_if_disabled() | |||
Pleroma.ApplicationRequirements.verify!() | |||
@@ -56,6 +56,7 @@ defmodule Pleroma.Config.DeprecationWarnings do | |||
check_old_mrf_config() | |||
check_media_proxy_whitelist_config() | |||
check_welcome_message_config() | |||
check_gun_pool_options() | |||
end | |||
def check_welcome_message_config do | |||
@@ -115,4 +116,46 @@ defmodule Pleroma.Config.DeprecationWarnings do | |||
""") | |||
end | |||
end | |||
def check_gun_pool_options do | |||
pool_config = Config.get(:connections_pool) | |||
if timeout = pool_config[:await_up_timeout] do | |||
Logger.warn(""" | |||
!!!DEPRECATION WARNING!!! | |||
Your config is using old setting name `await_up_timeout` instead of `connect_timeout`. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later. | |||
""") | |||
Config.put(:connections_pool, Keyword.put_new(pool_config, :connect_timeout, timeout)) | |||
end | |||
pools_configs = Config.get(:pools) | |||
warning_preface = """ | |||
!!!DEPRECATION WARNING!!! | |||
Your config is using old setting name `timeout` instead of `recv_timeout` in pool settings. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later. | |||
""" | |||
updated_config = | |||
Enum.reduce(pools_configs, [], fn {pool_name, config}, acc -> | |||
if timeout = config[:timeout] do | |||
Keyword.put(acc, pool_name, Keyword.put_new(config, :recv_timeout, timeout)) | |||
else | |||
acc | |||
end | |||
end) | |||
if updated_config != [] do | |||
pool_warnings = | |||
updated_config | |||
|> Keyword.keys() | |||
|> Enum.map(fn pool_name -> | |||
"\n* `:timeout` options in #{pool_name} pool is now `:recv_timeout`" | |||
end) | |||
Logger.warn(Enum.join([warning_preface | pool_warnings])) | |||
Config.put(:pools, updated_config) | |||
end | |||
end | |||
end |
@@ -0,0 +1,30 @@ | |||
defmodule Pleroma.Config.Oban do | |||
require Logger | |||
def warn do | |||
oban_config = Pleroma.Config.get(Oban) | |||
crontab = | |||
[Pleroma.Workers.Cron.StatsWorker] | |||
|> Enum.reduce(oban_config[:crontab], fn removed_worker, acc -> | |||
with acc when is_list(acc) <- acc, | |||
setting when is_tuple(setting) <- | |||
Enum.find(acc, fn {_, worker} -> worker == removed_worker end) do | |||
""" | |||
!!!OBAN CONFIG WARNING!!! | |||
You are using old workers in Oban crontab settings, which were removed. | |||
Please, remove setting from crontab in your config file (prod.secret.exs): #{ | |||
inspect(setting) | |||
} | |||
""" | |||
|> Logger.warn() | |||
List.delete(acc, setting) | |||
else | |||
_ -> acc | |||
end | |||
end) | |||
Pleroma.Config.put(Oban, Keyword.put(oban_config, :crontab, crontab)) | |||
end | |||
end |
@@ -13,7 +13,7 @@ defmodule Pleroma.Gun.Conn do | |||
opts = | |||
opts | |||
|> Enum.into(%{}) | |||
|> Map.put_new(:await_up_timeout, pool_opts[:await_up_timeout] || 5_000) | |||
|> Map.put_new(:connect_timeout, pool_opts[:connect_timeout] || 5_000) | |||
|> Map.put_new(:supervise, false) | |||
|> maybe_add_tls_opts(uri) | |||
@@ -50,7 +50,7 @@ defmodule Pleroma.Gun.Conn do | |||
with open_opts <- Map.delete(opts, :tls_opts), | |||
{:ok, conn} <- Gun.open(proxy_host, proxy_port, open_opts), | |||
{:ok, _} <- Gun.await_up(conn, opts[:await_up_timeout]), | |||
{:ok, _} <- Gun.await_up(conn, opts[:connect_timeout]), | |||
stream <- Gun.connect(conn, connect_opts), | |||
{:response, :fin, 200, _} <- Gun.await(conn, stream) do | |||
{:ok, conn} | |||
@@ -88,7 +88,7 @@ defmodule Pleroma.Gun.Conn do | |||
|> Map.put(:socks_opts, socks_opts) | |||
with {:ok, conn} <- Gun.open(proxy_host, proxy_port, opts), | |||
{:ok, _} <- Gun.await_up(conn, opts[:await_up_timeout]) do | |||
{:ok, _} <- Gun.await_up(conn, opts[:connect_timeout]) do | |||
{:ok, conn} | |||
else | |||
error -> | |||
@@ -106,7 +106,7 @@ defmodule Pleroma.Gun.Conn do | |||
host = Pleroma.HTTP.AdapterHelper.parse_host(host) | |||
with {:ok, conn} <- Gun.open(host, port, opts), | |||
{:ok, _} <- Gun.await_up(conn, opts[:await_up_timeout]) do | |||
{:ok, _} <- Gun.await_up(conn, opts[:connect_timeout]) do | |||
{:ok, conn} | |||
else | |||
error -> | |||
@@ -100,21 +100,27 @@ defmodule Pleroma.HTML do | |||
end) | |||
end | |||
def extract_first_external_url(_, nil), do: {:error, "No content"} | |||
def extract_first_external_url_from_object(%{data: %{"content" => content}} = object) | |||
when is_binary(content) do | |||
unless object.data["fake"] do | |||
key = "URL|#{object.id}" | |||
Cachex.fetch!(:scrubber_cache, key, fn _key -> | |||
{:commit, {:ok, extract_first_external_url(content)}} | |||
end) | |||
else | |||
{:ok, extract_first_external_url(content)} | |||
end | |||
end | |||
def extract_first_external_url(object, content) do | |||
key = "URL|#{object.id}" | |||
def extract_first_external_url_from_object(_), do: {:error, :no_content} | |||
Cachex.fetch!(:scrubber_cache, key, fn _key -> | |||
result = | |||
content | |||
|> Floki.parse_fragment!() | |||
|> Floki.find("a:not(.mention,.hashtag,.attachment,[rel~=\"tag\"])") | |||
|> Enum.take(1) | |||
|> Floki.attribute("href") | |||
|> Enum.at(0) | |||
{:commit, {:ok, result}} | |||
end) | |||
def extract_first_external_url(content) do | |||
content | |||
|> Floki.parse_fragment!() | |||
|> Floki.find("a:not(.mention,.hashtag,.attachment,[rel~=\"tag\"])") | |||
|> Enum.take(1) | |||
|> Floki.attribute("href") | |||
|> Enum.at(0) | |||
end | |||
end |
@@ -6,7 +6,7 @@ defmodule Pleroma.HTTP.AdapterHelper do | |||
@moduledoc """ | |||
Configure Tesla.Client with default and customized adapter options. | |||
""" | |||
@defaults [pool: :federation] | |||
@defaults [pool: :federation, connect_timeout: 5_000, recv_timeout: 5_000] | |||
@type proxy_type() :: :socks4 | :socks5 | |||
@type host() :: charlist() | :inet.ip_address() | |||
@@ -11,12 +11,8 @@ defmodule Pleroma.HTTP.AdapterHelper.Gun do | |||
require Logger | |||
@defaults [ | |||
connect_timeout: 5_000, | |||
domain_lookup_timeout: 5_000, | |||
tls_handshake_timeout: 5_000, | |||
retry: 1, | |||
retry_timeout: 1000, | |||
await_up_timeout: 5_000 | |||
retry_timeout: 1_000 | |||
] | |||
@type pool() :: :federation | :upload | :media | :default | |||
@@ -45,15 +41,17 @@ defmodule Pleroma.HTTP.AdapterHelper.Gun do | |||
end | |||
defp put_timeout(opts) do | |||
{recv_timeout, opts} = Keyword.pop(opts, :recv_timeout, pool_timeout(opts[:pool])) | |||
# this is the timeout to receive a message from Gun | |||
Keyword.put_new(opts, :timeout, pool_timeout(opts[:pool])) | |||
# `:timeout` key is used in Tesla | |||
Keyword.put(opts, :timeout, recv_timeout) | |||
end | |||
@spec pool_timeout(pool()) :: non_neg_integer() | |||
def pool_timeout(pool) do | |||
default = Config.get([:pools, :default, :timeout], 5_000) | |||
default = Config.get([:pools, :default, :recv_timeout], 5_000) | |||
Config.get([:pools, pool, :timeout], default) | |||
Config.get([:pools, pool, :recv_timeout], default) | |||
end | |||
@prefix Pleroma.Gun.ConnectionPool | |||
@@ -2,11 +2,8 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do | |||
@behaviour Pleroma.HTTP.AdapterHelper | |||
@defaults [ | |||
connect_timeout: 10_000, | |||
recv_timeout: 20_000, | |||
follow_redirect: true, | |||
force_redirect: true, | |||
pool: :federation | |||
force_redirect: true | |||
] | |||
@spec options(keyword(), URI.t()) :: keyword() | |||
@@ -19,8 +16,21 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do | |||
|> Keyword.merge(config_opts) | |||
|> Keyword.merge(connection_opts) | |||
|> add_scheme_opts(uri) | |||
|> maybe_add_with_body() | |||
|> Pleroma.HTTP.AdapterHelper.maybe_add_proxy(proxy) | |||
end | |||
defp add_scheme_opts(opts, %URI{scheme: "https"}) do | |||
Keyword.put(opts, :ssl_options, versions: [:"tlsv1.2", :"tlsv1.1", :tlsv1]) | |||
end | |||
defp add_scheme_opts(opts, _), do: opts | |||
defp maybe_add_with_body(opts) do | |||
if opts[:max_body] do | |||
Keyword.put(opts, :with_body, true) | |||
else | |||
opts | |||
end | |||
end | |||
end |
@@ -11,7 +11,7 @@ defmodule Pleroma.HTTP.ExAws do | |||
@impl true | |||
def request(method, url, body \\ "", headers \\ [], http_opts \\ []) do | |||
http_opts = Keyword.put_new(http_opts, :adapter, pool: :upload) | |||
http_opts = Keyword.put_new(http_opts, :pool, :upload) | |||
case HTTP.request(method, url, body, headers, http_opts) do | |||
{:ok, env} -> | |||
@@ -60,7 +60,7 @@ defmodule Pleroma.HTTP do | |||
{:ok, Env.t()} | {:error, any()} | |||
def request(method, url, body, headers, options) when is_binary(url) do | |||
uri = URI.parse(url) | |||
adapter_opts = AdapterHelper.options(uri, options[:adapter] || []) | |||
adapter_opts = AdapterHelper.options(uri, options || []) | |||
options = put_in(options[:adapter], adapter_opts) | |||
params = options[:params] || [] | |||
@@ -11,7 +11,7 @@ defmodule Pleroma.HTTP.Tzdata do | |||
@impl true | |||
def get(url, headers, options) do | |||
options = Keyword.put_new(options, :adapter, pool: :default) | |||
options = Keyword.put_new(options, :pool, :default) | |||
with {:ok, %Tesla.Env{} = env} <- HTTP.get(url, headers, options) do | |||
{:ok, {env.status, env.headers, env.body}} | |||
@@ -20,7 +20,7 @@ defmodule Pleroma.HTTP.Tzdata do | |||
@impl true | |||
def head(url, headers, options) do | |||
options = Keyword.put_new(options, :adapter, pool: :default) | |||
options = Keyword.put_new(options, :pool, :default) | |||
with {:ok, %Tesla.Env{} = env} <- HTTP.head(url, headers, options) do | |||
{:ok, {env.status, env.headers}} | |||
@@ -14,6 +14,8 @@ defmodule Pleroma.Instances.Instance do | |||
import Ecto.Query | |||
import Ecto.Changeset | |||
require Logger | |||
schema "instances" do | |||
field(:host, :string) | |||
field(:unreachable_since, :naive_datetime_usec) | |||
@@ -145,6 +147,10 @@ defmodule Pleroma.Instances.Instance do | |||
favicon | |||
end | |||
rescue | |||
e -> | |||
Logger.warn("Instance.get_or_update_favicon(\"#{host}\") error: #{inspect(e)}") | |||
nil | |||
end | |||
defp scrape_favicon(%URI{} = instance_uri) do | |||
@@ -165,7 +171,12 @@ defmodule Pleroma.Instances.Instance do | |||
_ -> nil | |||
end | |||
rescue | |||
_ -> nil | |||
e -> | |||
Logger.warn( | |||
"Instance.scrape_favicon(\"#{to_string(instance_uri)}\") error: #{inspect(e)}" | |||
) | |||
nil | |||
end | |||
end | |||
end |
@@ -7,6 +7,7 @@ defmodule Pleroma.ReverseProxy.Client.Hackney do | |||
@impl true | |||
def request(method, url, headers, body, opts \\ []) do | |||
opts = Keyword.put(opts, :ssl_options, versions: [:"tlsv1.2", :"tlsv1.1", :tlsv1]) | |||
:hackney.request(method, url, headers, body, opts) | |||
end | |||
@@ -3,12 +3,15 @@ | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Stats do | |||
use GenServer | |||
import Ecto.Query | |||
alias Pleroma.CounterCache | |||
alias Pleroma.Repo | |||
alias Pleroma.User | |||
use GenServer | |||
@interval :timer.seconds(60) | |||
def start_link(_) do | |||
GenServer.start_link( | |||
@@ -18,6 +21,12 @@ defmodule Pleroma.Stats do | |||
) | |||
end | |||
@impl true | |||
def init(_args) do | |||
if Pleroma.Config.get(:env) == :test, do: :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo) | |||
{:ok, nil, {:continue, :calculate_stats}} | |||
end | |||
@doc "Performs update stats" | |||
def force_update do | |||
GenServer.call(__MODULE__, :force_update) | |||
@@ -29,7 +38,11 @@ defmodule Pleroma.Stats do | |||
end | |||
@doc "Returns stats data" | |||
@spec get_stats() :: %{domain_count: integer(), status_count: integer(), user_count: integer()} | |||
@spec get_stats() :: %{ | |||
domain_count: non_neg_integer(), | |||
status_count: non_neg_integer(), | |||
user_count: non_neg_integer() | |||
} | |||
def get_stats do | |||
%{stats: stats} = GenServer.call(__MODULE__, :get_state) | |||
@@ -44,25 +57,14 @@ defmodule Pleroma.Stats do | |||
peers | |||
end | |||
def init(_args) do | |||
{:ok, calculate_stat_data()} | |||
end | |||
def handle_call(:force_update, _from, _state) do | |||
new_stats = calculate_stat_data() | |||
{:reply, new_stats, new_stats} | |||
end | |||
def handle_call(:get_state, _from, state) do | |||
{:reply, state, state} | |||
end | |||
def handle_cast(:run_update, _state) do | |||
new_stats = calculate_stat_data() | |||
{:noreply, new_stats} | |||
end | |||
@spec calculate_stat_data() :: %{ | |||
peers: list(), | |||
stats: %{ | |||
domain_count: non_neg_integer(), | |||
status_count: non_neg_integer(), | |||
user_count: non_neg_integer() | |||
} | |||
} | |||
def calculate_stat_data do | |||
peers = | |||
from( | |||
@@ -97,6 +99,7 @@ defmodule Pleroma.Stats do | |||
} | |||
end | |||
@spec get_status_visibility_count(String.t() | nil) :: map() | |||
def get_status_visibility_count(instance \\ nil) do | |||
if is_nil(instance) do | |||
CounterCache.get_sum() | |||
@@ -104,4 +107,36 @@ defmodule Pleroma.Stats do | |||
CounterCache.get_by_instance(instance) | |||
end | |||
end | |||
@impl true | |||
def handle_continue(:calculate_stats, _) do | |||
stats = calculate_stat_data() | |||
Process.send_after(self(), :run_update, @interval) | |||
{:noreply, stats} | |||
end | |||
@impl true | |||
def handle_call(:force_update, _from, _state) do | |||
new_stats = calculate_stat_data() | |||
{:reply, new_stats, new_stats} | |||
end | |||
@impl true | |||
def handle_call(:get_state, _from, state) do | |||
{:reply, state, state} | |||
end | |||
@impl true | |||
def handle_cast(:run_update, _state) do | |||
new_stats = calculate_stat_data() | |||
{:noreply, new_stats} | |||
end | |||
@impl true | |||
def handle_info(:run_update, _) do | |||
new_stats = calculate_stat_data() | |||
Process.send_after(self(), :run_update, @interval) | |||
{:noreply, new_stats} | |||
end | |||
end |
@@ -15,7 +15,11 @@ defmodule Pleroma.Upload.Filter do | |||
require Logger | |||
@callback filter(Pleroma.Upload.t()) :: :ok | {:ok, Pleroma.Upload.t()} | {:error, any()} | |||
@callback filter(Pleroma.Upload.t()) :: | |||
{:ok, :filtered} | |||
| {:ok, :noop} | |||
| {:ok, :filtered, Pleroma.Upload.t()} | |||
| {:error, any()} | |||
@spec filter([module()], Pleroma.Upload.t()) :: {:ok, Pleroma.Upload.t()} | {:error, any()} | |||
@@ -25,10 +29,13 @@ defmodule Pleroma.Upload.Filter do | |||
def filter([filter | rest], upload) do | |||
case filter.filter(upload) do | |||
:ok -> | |||
{:ok, :filtered} -> | |||
filter(rest, upload) | |||
{:ok, upload} -> | |||
{:ok, :filtered, upload} -> | |||
filter(rest, upload) | |||
{:ok, :noop} -> | |||
filter(rest, upload) | |||
error -> | |||
@@ -16,9 +16,11 @@ defmodule Pleroma.Upload.Filter.AnonymizeFilename do | |||
def filter(%Upload{name: name} = upload) do | |||
extension = List.last(String.split(name, ".")) | |||
name = predefined_name(extension) || random(extension) | |||
{:ok, %Upload{upload | name: name}} | |||
{:ok, :filtered, %Upload{upload | name: name}} | |||
end | |||
def filter(_), do: {:ok, :noop} | |||
@spec predefined_name(String.t()) :: String.t() | nil | |||
defp predefined_name(extension) do | |||
with name when not is_nil(name) <- Config.get([__MODULE__, :text]), | |||
@@ -17,8 +17,8 @@ defmodule Pleroma.Upload.Filter.Dedupe do | |||
|> Base.encode16(case: :lower) | |||
filename = shasum <> "." <> extension | |||
{:ok, %Upload{upload | id: shasum, path: filename}} | |||
{:ok, :filtered, %Upload{upload | id: shasum, path: filename}} | |||
end | |||
def filter(_), do: :ok | |||
def filter(_), do: {:ok, :noop} | |||
end |
@@ -9,11 +9,15 @@ defmodule Pleroma.Upload.Filter.Exiftool do | |||
""" | |||
@behaviour Pleroma.Upload.Filter | |||
@spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()} | |||
@spec filter(Pleroma.Upload.t()) :: {:ok, any()} | {:error, String.t()} | |||
# webp is not compatible with exiftool at this time | |||
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop} | |||
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do | |||
try do | |||
case System.cmd("exiftool", ["-overwrite_original", "-gps:all=", file], parallelism: true) do | |||
{_response, 0} -> :ok | |||
{_response, 0} -> {:ok, :filtered} | |||
{error, 1} -> {:error, error} | |||
end | |||
rescue | |||
@@ -22,5 +26,5 @@ defmodule Pleroma.Upload.Filter.Exiftool do | |||
end | |||
end | |||
def filter(_), do: :ok | |||
def filter(_), do: {:ok, :noop} | |||
end |
@@ -38,16 +38,16 @@ defmodule Pleroma.Upload.Filter.Mogrifun do | |||
[{"fill", "yellow"}, {"tint", "40"}] | |||
] | |||
@spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()} | |||
@spec filter(Pleroma.Upload.t()) :: {:ok, atom()} | {:error, String.t()} | |||
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do | |||
try do | |||
Filter.Mogrify.do_filter(file, [Enum.random(@filters)]) | |||
:ok | |||
{:ok, :filtered} | |||
rescue | |||
_e in ErlangError -> | |||
{:error, "mogrify command not found"} | |||
end | |||
end | |||
def filter(_), do: :ok | |||
def filter(_), do: {:ok, :noop} | |||
end |
@@ -8,18 +8,18 @@ defmodule Pleroma.Upload.Filter.Mogrify do | |||
@type conversion :: action :: String.t() | {action :: String.t(), opts :: String.t()} | |||
@type conversions :: conversion() | [conversion()] | |||
@spec filter(Pleroma.Upload.t()) :: :ok | {:error, String.t()} | |||
@spec filter(Pleroma.Upload.t()) :: {:ok, :atom} | {:error, String.t()} | |||
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do | |||
try do | |||
do_filter(file, Pleroma.Config.get!([__MODULE__, :args])) | |||
:ok | |||
{:ok, :filtered} | |||
rescue | |||
_e in ErlangError -> | |||
{:error, "mogrify command not found"} | |||
end | |||
end | |||
def filter(_), do: :ok | |||
def filter(_), do: {:ok, :noop} | |||
def do_filter(file, filters) do | |||
file | |||
@@ -1125,31 +1125,31 @@ defmodule Pleroma.User do | |||
User.Query.build(%{followers: user, deactivated: false}) | |||
end | |||
def get_followers_query(user, page) do | |||
def get_followers_query(%User{} = user, page) do | |||
user | |||
|> get_followers_query(nil) | |||
|> User.Query.paginate(page, 20) | |||
end | |||
@spec get_followers_query(User.t()) :: Ecto.Query.t() | |||
def get_followers_query(user), do: get_followers_query(user, nil) | |||
def get_followers_query(%User{} = user), do: get_followers_query(user, nil) | |||
@spec get_followers(User.t(), pos_integer() | nil) :: {:ok, list(User.t())} | |||
def get_followers(user, page \\ nil) do | |||
def get_followers(%User{} = user, page \\ nil) do | |||
user | |||
|> get_followers_query(page) | |||
|> Repo.all() | |||
end | |||
@spec get_external_followers(User.t(), pos_integer() | nil) :: {:ok, list(User.t())} | |||
def get_external_followers(user, page \\ nil) do | |||
def get_external_followers(%User{} = user, page \\ nil) do | |||
user | |||
|> get_followers_query(page) | |||
|> User.Query.build(%{external: true}) | |||
|> Repo.all() | |||
end | |||
def get_followers_ids(user, page \\ nil) do | |||
def get_followers_ids(%User{} = user, page \\ nil) do | |||
user | |||
|> get_followers_query(page) | |||
|> select([u], u.id) | |||
@@ -1161,29 +1161,29 @@ defmodule Pleroma.User do | |||
User.Query.build(%{friends: user, deactivated: false}) | |||
end | |||
def get_friends_query(user, page) do | |||
def get_friends_query(%User{} = user, page) do | |||
user | |||
|> get_friends_query(nil) | |||
|> User.Query.paginate(page, 20) | |||
end | |||
@spec get_friends_query(User.t()) :: Ecto.Query.t() | |||
def get_friends_query(user), do: get_friends_query(user, nil) | |||
def get_friends_query(%User{} = user), do: get_friends_query(user, nil) | |||
def get_friends(user, page \\ nil) do | |||
def get_friends(%User{} = user, page \\ nil) do | |||
user | |||
|> get_friends_query(page) | |||
|> Repo.all() | |||
end | |||
def get_friends_ap_ids(user) do | |||
def get_friends_ap_ids(%User{} = user) do | |||
user | |||
|> get_friends_query(nil) | |||
|> select([u], u.ap_id) | |||
|> Repo.all() | |||
end | |||
def get_friends_ids(user, page \\ nil) do | |||
def get_friends_ids(%User{} = user, page \\ nil) do | |||
user | |||
|> get_friends_query(page) | |||
|> select([u], u.id) | |||
@@ -115,8 +115,8 @@ defmodule Pleroma.User.Search do | |||
) | |||
end | |||
defp base_query(_user, false), do: User | |||
defp base_query(user, true), do: User.get_friends_query(user) | |||
defp base_query(%User{} = user, true), do: User.get_friends_query(user) | |||
defp base_query(_user, _following), do: User | |||
defp filter_invisible_users(query) do | |||
from(q in query, where: q.invisible == false) | |||
@@ -399,21 +399,30 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do | |||
defp handle_user_activity( | |||
%User{} = user, | |||
%{"type" => "Create", "object" => %{"type" => "Note"}} = params | |||
%{"type" => "Create", "object" => %{"type" => "Note"} = object} = params | |||
) do | |||
object = | |||
params["object"] | |||
|> Map.merge(Map.take(params, ["to", "cc"])) | |||
|> Map.put("attributedTo", user.ap_id()) | |||
|> Transmogrifier.fix_object() | |||
ActivityPub.create(%{ | |||
to: params["to"], | |||
actor: user, | |||
context: object["context"], | |||
object: object, | |||
additional: Map.take(params, ["cc"]) | |||
}) | |||
content = if is_binary(object["content"]), do: object["content"], else: "" | |||
name = if is_binary(object["name"]), do: object["name"], else: "" | |||
summary = if is_binary(object["summary"]), do: object["summary"], else: "" | |||
length = String.length(content <> name <> summary) | |||
if length > Pleroma.Config.get([:instance, :limit]) do | |||
{:error, dgettext("errors", "Note is over the character limit")} | |||
else | |||
object = | |||
object | |||
|> Map.merge(Map.take(params, ["to", "cc"])) | |||
|> Map.put("attributedTo", user.ap_id()) | |||
|> Transmogrifier.fix_object() | |||
ActivityPub.create(%{ | |||
to: params["to"], | |||
actor: user, | |||
context: object["context"], | |||
object: object, | |||
additional: Map.take(params, ["cc"]) | |||
}) | |||
end | |||
end | |||
defp handle_user_activity(%User{} = user, %{"type" => "Delete"} = params) do | |||
@@ -0,0 +1,56 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy do | |||
alias Pleroma.User | |||
@behaviour Pleroma.Web.ActivityPub.MRF | |||
@moduledoc "Remove bot posts from federated timeline" | |||
require Pleroma.Constants | |||
defp check_by_actor_type(user), do: user.actor_type in ["Application", "Service"] | |||
defp check_by_nickname(user), do: Regex.match?(~r/bot@|ebooks@/i, user.nickname) | |||
defp check_if_bot(user), do: check_by_actor_type(user) or check_by_nickname(user) | |||
@impl true | |||
def filter( | |||
%{ | |||
"type" => "Create", | |||
"to" => to, | |||
"cc" => cc, | |||
"actor" => actor, | |||
"object" => object | |||
} = message | |||
) do | |||
user = User.get_cached_by_ap_id(actor) | |||
isbot = check_if_bot(user) | |||
if isbot and Enum.member?(to, Pleroma.Constants.as_public()) do | |||
to = List.delete(to, Pleroma.Constants.as_public()) ++ [user.follower_address] | |||
cc = List.delete(cc, user.follower_address) ++ [Pleroma.Constants.as_public()] | |||
object = | |||
object | |||
|> Map.put("to", to) | |||
|> Map.put("cc", cc) | |||
message = | |||
message | |||
|> Map.put("to", to) | |||
|> Map.put("cc", cc) | |||
|> Map.put("object", object) | |||
{:ok, message} | |||
else | |||
{:ok, message} | |||
end | |||
end | |||
@impl true | |||
def filter(message), do: {:ok, message} | |||
@impl true | |||
def describe, do: {:ok, %{}} | |||
end |
@@ -379,8 +379,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do | |||
filters | |||
|> String.split(",") | |||
|> Enum.filter(&Enum.member?(@filters, &1)) | |||
|> Enum.map(&String.to_atom/1) | |||
|> Map.new(&{&1, true}) | |||
|> Map.new(&{String.to_existing_atom(&1), true}) | |||
end | |||
def right_add_multiple(%{assigns: %{user: admin}} = conn, %{ | |||
@@ -9,7 +9,15 @@ defmodule Pleroma.Web.Feed.TagController do | |||
alias Pleroma.Web.ActivityPub.ActivityPub | |||
alias Pleroma.Web.Feed.FeedView | |||
def feed(conn, %{"tag" => raw_tag} = params) do | |||
def feed(conn, params) do | |||
unless Pleroma.Config.restrict_unauthenticated_access?(:activities, :local) do | |||
render_feed(conn, params) | |||
else | |||
render_error(conn, :not_found, "Not found") | |||
end | |||
end | |||
def render_feed(conn, %{"tag" => raw_tag} = params) do | |||
{format, tag} = parse_tag(raw_tag) | |||
activities = | |||
@@ -37,7 +37,15 @@ defmodule Pleroma.Web.Feed.UserController do | |||
end | |||
end | |||
def feed(conn, %{"nickname" => nickname} = params) do | |||
def feed(conn, params) do | |||
unless Pleroma.Config.restrict_unauthenticated_access?(:profiles, :local) do | |||
render_feed(conn, params) | |||
else | |||
errors(conn, {:error, :not_found}) | |||
end | |||
end | |||
def render_feed(conn, %{"nickname" => nickname} = params) do | |||
format = get_format(conn) | |||
format = | |||
@@ -7,8 +7,9 @@ defmodule Pleroma.Web.Metadata do | |||
def build_tags(params) do | |||
providers = [ | |||
Pleroma.Web.Metadata.Providers.RelMe, | |||
Pleroma.Web.Metadata.Providers.RestrictIndexing | |||
| Pleroma.Config.get([__MODULE__, :providers], []) | |||
| activated_providers() | |||
] | |||
Enum.reduce(providers, "", fn parser, acc -> | |||
@@ -42,4 +43,12 @@ defmodule Pleroma.Web.Metadata do | |||
def activity_nsfw?(_) do | |||
false | |||
end | |||
defp activated_providers do | |||
unless Pleroma.Config.restrict_unauthenticated_access?(:activities, :local) do | |||
[Pleroma.Web.Metadata.Providers.Feed | Pleroma.Config.get([__MODULE__, :providers], [])] | |||
else | |||
[] | |||
end | |||
end | |||
end |
@@ -5,7 +5,8 @@ | |||
defmodule Pleroma.Web.RelMe do | |||
@options [ | |||
pool: :media, | |||
max_body: 2_000_000 | |||
max_body: 2_000_000, | |||
recv_timeout: 2_000 | |||
] | |||
if Pleroma.Config.get(:env) == :test do | |||
@@ -23,18 +24,8 @@ defmodule Pleroma.Web.RelMe do | |||
def parse(_), do: {:error, "No URL provided"} | |||
defp parse_url(url) do | |||
opts = | |||
if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do | |||
Keyword.merge(@options, | |||
recv_timeout: 2_000, | |||
with_body: true | |||
) | |||
else | |||
@options | |||
end | |||
with {:ok, %Tesla.Env{body: html, status: status}} when status in 200..299 <- | |||
Pleroma.HTTP.get(url, [], adapter: opts), | |||
Pleroma.HTTP.get(url, [], @options), | |||
{:ok, html_tree} <- Floki.parse_document(html), | |||
data <- | |||
Floki.attribute(html_tree, "link[rel~=me]", "href") ++ | |||
@@ -9,14 +9,15 @@ defmodule Pleroma.Web.RichMedia.Helpers do | |||
alias Pleroma.Object | |||
alias Pleroma.Web.RichMedia.Parser | |||
@rich_media_options [ | |||
@options [ | |||
pool: :media, | |||
max_body: 2_000_000 | |||
max_body: 2_000_000, | |||
recv_timeout: 2_000 | |||
] | |||
@spec validate_page_url(URI.t() | binary()) :: :ok | :error | |||
defp validate_page_url(page_url) when is_binary(page_url) do | |||
validate_tld = Pleroma.Config.get([Pleroma.Formatter, :validate_tld]) | |||
validate_tld = Config.get([Pleroma.Formatter, :validate_tld]) | |||
page_url | |||
|> Linkify.Parser.url?(validate_tld: validate_tld) | |||
@@ -58,7 +59,7 @@ defmodule Pleroma.Web.RichMedia.Helpers do | |||
with true <- Config.get([:rich_media, :enabled]), | |||
false <- object.data["sensitive"] || false, | |||
{:ok, page_url} <- | |||
HTML.extract_first_external_url(object, object.data["content"]), | |||
HTML.extract_first_external_url_from_object(object), | |||
:ok <- validate_page_url(page_url), | |||
{:ok, rich_media} <- Parser.parse(page_url) do | |||
%{page_url: page_url, rich_media: rich_media} | |||
@@ -86,16 +87,6 @@ defmodule Pleroma.Web.RichMedia.Helpers do | |||
def rich_media_get(url) do | |||
headers = [{"user-agent", Pleroma.Application.user_agent() <> "; Bot"}] | |||
options = | |||
if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Hackney do | |||
Keyword.merge(@rich_media_options, | |||
recv_timeout: 2_000, | |||
with_body: true | |||
) | |||
else | |||
@rich_media_options | |||
end | |||
Pleroma.HTTP.get(url, headers, adapter: options) | |||
Pleroma.HTTP.get(url, headers, @options) | |||
end | |||
end |
@@ -21,8 +21,13 @@ defmodule Pleroma.Web.RichMedia.Parser do | |||
{:ok, _} <- set_ttl_based_on_image(data, url) do | |||
{:ok, data} | |||
else | |||
{:error, {:invalid_metadata, data}} = e -> | |||
Logger.debug(fn -> "Incomplete or invalid metadata for #{url}: #{inspect(data)}" end) | |||
e | |||
error -> | |||
Logger.error(fn -> "Rich media error: #{inspect(error)}" end) | |||
Logger.error(fn -> "Rich media error for #{url}: #{inspect(error)}" end) | |||
error | |||
end | |||
end | |||
@@ -90,7 +95,7 @@ defmodule Pleroma.Web.RichMedia.Parser do | |||
end) | |||
end | |||
defp parse_url(url) do | |||
def parse_url(url) do | |||
with {:ok, %Tesla.Env{body: html}} <- Pleroma.Web.RichMedia.Helpers.rich_media_get(url), | |||
{:ok, html} <- Floki.parse_document(html) do | |||
html | |||
@@ -116,7 +121,7 @@ defmodule Pleroma.Web.RichMedia.Parser do | |||
end | |||
defp check_parsed_data(data) do | |||
{:error, "Found metadata was invalid or incomplete: #{inspect(data)}"} | |||
{:error, {:invalid_metadata, data}} | |||
end | |||
defp clean_parsed_data(data) do | |||
@@ -1,17 +0,0 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Workers.Cron.StatsWorker do | |||
@moduledoc """ | |||
The worker to update peers statistics. | |||
""" | |||
use Oban.Worker, queue: "background" | |||
@impl Oban.Worker | |||
def perform(_job) do | |||
Pleroma.Stats.do_collect() | |||
:ok | |||
end | |||
end |
@@ -134,8 +134,8 @@ defmodule Pleroma.Mixfile do | |||
{:cachex, "~> 3.2"}, | |||
{:poison, "~> 3.0", override: true}, | |||
{:tesla, | |||
git: "https://git.pleroma.social/pleroma/elixir-libraries/tesla.git", | |||
ref: "3a2789d8535f7b520ebbadc4494227e5ba0e5365", | |||
git: "https://github.com/teamon/tesla/", | |||
ref: "9f7261ca49f9f901ceb73b60219ad6f8a9f6aa30", | |||
override: true}, | |||
{:castore, "~> 0.1"}, | |||
{:cowlib, "~> 2.9", override: true}, | |||
@@ -180,7 +180,7 @@ defmodule Pleroma.Mixfile do | |||
{:flake_id, "~> 0.1.0"}, | |||
{:concurrent_limiter, | |||
git: "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", | |||
ref: "55e92f84b4ed531bd487952a71040a9c69dc2807"}, | |||
ref: "d81be41024569330f296fc472e24198d7499ba78"}, | |||
{:remote_ip, | |||
git: "https://git.pleroma.social/pleroma/remote_ip.git", | |||
ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"}, | |||
@@ -197,7 +197,9 @@ defmodule Pleroma.Mixfile do | |||
{:ex_machina, "~> 2.4", only: :test}, | |||
{:credo, "~> 1.4", only: [:dev, :test], runtime: false}, | |||
{:mock, "~> 0.3.5", only: :test}, | |||
{:excoveralls, "~> 0.13.1", only: :test}, | |||
# temporary downgrade for excoveralls, hackney until hackney max_connections bug will be fixed | |||
{:excoveralls, "0.12.3", only: :test}, | |||
{:hackney, "1.15.2", override: true}, | |||
{:mox, "~> 0.5", only: :test}, | |||
{:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test} | |||
] ++ oauth_deps() | |||
@@ -11,10 +11,10 @@ | |||
"calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"}, | |||
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]}, | |||
"castore": {:hex, :castore, "0.1.7", "1ca19eee705cde48c9e809e37fdd0730510752cc397745e550f6065a56a701e9", [:mix], [], "hexpm", "a2ae2c13d40e9c308387f1aceb14786dca019ebc2a11484fb2a9f797ea0aa0d8"}, | |||
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"}, | |||
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"}, | |||
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, | |||
"comeonin": {:hex, :comeonin, "5.3.1", "7fe612b739c78c9c1a75186ef2d322ce4d25032d119823269d0aa1e2f1e20025", [:mix], [], "hexpm", "d6222483060c17f0977fad1b7401ef0c5863c985a64352755f366aee3799c245"}, | |||
"concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", "55e92f84b4ed531bd487952a71040a9c69dc2807", [ref: "55e92f84b4ed531bd487952a71040a9c69dc2807"]}, | |||
"concurrent_limiter": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/concurrent_limiter.git", "d81be41024569330f296fc472e24198d7499ba78", [ref: "d81be41024569330f296fc472e24198d7499ba78"]}, | |||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"}, | |||
"cors_plug": {:hex, :cors_plug, "2.0.2", "2b46083af45e4bc79632bd951550509395935d3e7973275b2b743bd63cc942ce", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f0d0e13f71c51fd4ef8b2c7e051388e4dfb267522a83a22392c856de7e46465f"}, | |||
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"}, | |||
@@ -42,7 +42,7 @@ | |||
"ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"}, | |||
"ex_machina": {:hex, :ex_machina, "2.4.0", "09a34c5d371bfb5f78399029194a8ff67aff340ebe8ba19040181af35315eabb", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "a20bc9ddc721b33ea913b93666c5d0bdca5cbad7a67540784ae277228832d72c"}, | |||
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"}, | |||
"excoveralls": {:hex, :excoveralls, "0.13.1", "b9f1697f7c9e0cfe15d1a1d737fb169c398803ffcbc57e672aa007e9fd42864c", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "b4bb550e045def1b4d531a37fb766cbbe1307f7628bf8f0414168b3f52021cce"}, | |||
"excoveralls": {:hex, :excoveralls, "0.12.3", "2142be7cb978a3ae78385487edda6d1aff0e482ffc6123877bb7270a8ffbcfe0", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "568a3e616c264283f5dea5b020783ae40eef3f7ee2163f7a67cbd7b35bcadada"}, | |||
"fast_html": {:hex, :fast_html, "2.0.4", "4910ee49f2f6b19692e3bf30bf97f1b6b7dac489cd6b0f34cd0fe3042c56ba30", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "3bb49d541dfc02ad5e425904f53376d758c09f89e521afc7d2b174b3227761ea"}, | |||
"fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"}, | |||
"flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"}, | |||
@@ -52,12 +52,12 @@ | |||
"gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"}, | |||
"gettext": {:hex, :gettext, "0.18.0", "406d6b9e0e3278162c2ae1de0a60270452c553536772167e2d701f028116f870", [:mix], [], "hexpm", "c3f850be6367ebe1a08616c2158affe4a23231c70391050bf359d5f92f66a571"}, | |||
"gun": {:git, "https://github.com/ninenines/gun.git", "921c47146b2d9567eac7e9a4d2ccc60fffd4f327", [ref: "921c47146b2d9567eac7e9a4d2ccc60fffd4f327"]}, | |||
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"}, | |||
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e0100f8ef7d1124222c11ad362c857d3df7cb5f4204054f9f0f4a728666591fc"}, | |||
"html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"}, | |||
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, | |||
"http_signatures": {:hex, :http_signatures, "0.1.0", "4e4b501a936dbf4cb5222597038a89ea10781776770d2e185849fa829686b34c", [:mix], [], "hexpm", "f8a7b3731e3fd17d38fa6e343fcad7b03d6874a3b0a108c8568a71ed9c2cf824"}, | |||
"httpoison": {:hex, :httpoison, "1.7.0", "abba7d086233c2d8574726227b6c2c4f6e53c4deae7fe5f6de531162ce9929a0", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "975cc87c845a103d3d1ea1ccfd68a2700c211a434d8428b10c323dc95dc5b980"}, | |||
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"}, | |||
"httpoison": {:hex, :httpoison, "1.6.2", "ace7c8d3a361cebccbed19c283c349b3d26991eff73a1eaaa8abae2e3c8089b6", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "aa2c74bd271af34239a3948779612f87df2422c2fdcfdbcec28d9c105f0773fe"}, | |||
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"}, | |||
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"}, | |||
"jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"}, | |||
"joken": {:hex, :joken, "2.2.0", "2daa1b12be05184aff7b5ace1d43ca1f81345962285fff3f88db74927c954d3a", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "b4f92e30388206f869dd25d1af628a1d99d7586e5cf0672f64d4df84c4d2f5e9"}, | |||
@@ -107,17 +107,17 @@ | |||
"recon": {:hex, :recon, "2.5.1", "430ffa60685ac1efdfb1fe4c97b8767c92d0d92e6e7c3e8621559ba77598678a", [:mix, :rebar3], [], "hexpm", "5721c6b6d50122d8f68cccac712caa1231f97894bab779eff5ff0f886cb44648"}, | |||
"remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8", [ref: "b647d0deecaa3acb140854fe4bda5b7e1dc6d1c8"]}, | |||
"sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"}, | |||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, | |||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"}, | |||
"sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"}, | |||
"swoosh": {:hex, :swoosh, "1.0.0", "c547cfc83f30e12d5d1fdcb623d7de2c2e29a5becfc68bf8f42ba4d23d2c2756", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "b3b08e463f876cb6167f7168e9ad99a069a724e124bcee61847e0e1ed13f4a0d"}, | |||
"syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"}, | |||
"telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"}, | |||
"tesla": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/tesla.git", "3a2789d8535f7b520ebbadc4494227e5ba0e5365", [ref: "3a2789d8535f7b520ebbadc4494227e5ba0e5365"]}, | |||
"tesla": {:git, "https://github.com/teamon/tesla/", "9f7261ca49f9f901ceb73b60219ad6f8a9f6aa30", [ref: "9f7261ca49f9f901ceb73b60219ad6f8a9f6aa30"]}, | |||
"timex": {:hex, :timex, "3.6.2", "845cdeb6119e2fef10751c0b247b6c59d86d78554c83f78db612e3290f819bc2", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "26030b46199d02a590be61c2394b37ea25a3664c02fafbeca0b24c972025d47a"}, | |||
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, | |||
"tzdata": {:hex, :tzdata, "1.0.3", "73470ad29dde46e350c60a66e6b360d3b99d2d18b74c4c349dbebbc27a09a3eb", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a6e1ee7003c4d04ecbd21dd3ec690d4c6662db5d3bbdd7262d53cdf5e7c746c1"}, | |||
"ueberauth": {:hex, :ueberauth, "0.6.3", "d42ace28b870e8072cf30e32e385579c57b9cc96ec74fa1f30f30da9c14f3cc0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "afc293d8a1140d6591b53e3eaf415ca92842cb1d32fad3c450c6f045f7f91b60"}, | |||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"}, | |||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"}, | |||
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"}, | |||
"web_push_encryption": {:hex, :web_push_encryption, "0.3.0", "598b5135e696fd1404dc8d0d7c0fa2c027244a4e5d5e5a98ba267f14fdeaabc8", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "f10bdd1afe527ede694749fb77a2f22f146a51b054c7fa541c9fd920fba7c875"}, | |||
"websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []}, | |||
@@ -0,0 +1,586 @@ | |||
msgid "" | |||
msgstr "" | |||
"Project-Id-Version: PACKAGE VERSION\n" | |||
"Report-Msgid-Bugs-To: \n" | |||
"POT-Creation-Date: 2020-09-09 09:49+0000\n" | |||
"PO-Revision-Date: 2020-09-09 10:52+0000\n" | |||
"Last-Translator: tarteka <info@tarteka.net>\n" | |||
"Language-Team: Spanish <https://translate.pleroma.social/projects/pleroma/" | |||
"pleroma/es/>\n" | |||
"Language: es\n" | |||
"MIME-Version: 1.0\n" | |||
"Content-Type: text/plain; charset=UTF-8\n" | |||
"Content-Transfer-Encoding: 8bit\n" | |||
"Plural-Forms: nplurals=2; plural=n != 1;\n" | |||
"X-Generator: Weblate 4.0.4\n" | |||
## This file is a PO Template file. | |||
## | |||
## `msgid`s here are often extracted from source code. | |||
## Add new translations manually only if they're dynamic | |||
## translations that can't be statically extracted. | |||
## | |||
## Run `mix gettext.extract` to bring this file up to | |||
## date. Leave `msgstr`s empty as changing them here as no | |||
## effect: edit them in PO (`.po`) files instead. | |||
## From Ecto.Changeset.cast/4 | |||
msgid "can't be blank" | |||
msgstr "no puede estar en blanco" | |||
## From Ecto.Changeset.unique_constraint/3 | |||
msgid "has already been taken" | |||
msgstr "ya está en uso" | |||
## From Ecto.Changeset.put_change/3 | |||
msgid "is invalid" | |||
msgstr "es inválido" | |||
## From Ecto.Changeset.validate_format/3 | |||
msgid "has invalid format" | |||
msgstr "el formato no es válido" | |||
## From Ecto.Changeset.validate_subset/3 | |||
msgid "has an invalid entry" | |||
msgstr "tiene una entrada inválida" | |||
## From Ecto.Changeset.validate_exclusion/3 | |||
msgid "is reserved" | |||
msgstr "está reservado" | |||
## From Ecto.Changeset.validate_confirmation/3 | |||
msgid "does not match confirmation" | |||
msgstr "la confirmación no coincide" | |||
## From Ecto.Changeset.no_assoc_constraint/3 | |||
msgid "is still associated with this entry" | |||
msgstr "todavía está asociado con esta entrada" | |||
msgid "are still associated with this entry" | |||
msgstr "todavía están asociados con esta entrada" | |||
## From Ecto.Changeset.validate_length/3 | |||
msgid "should be %{count} character(s)" | |||
msgid_plural "should be %{count} character(s)" | |||
msgstr[0] "debe tener %{count} carácter" | |||
msgstr[1] "debe tener %{count} caracteres" | |||
msgid "should have %{count} item(s)" | |||
msgid_plural "should have %{count} item(s)" | |||
msgstr[0] "" | |||
msgstr[1] "" | |||
msgid "should be at least %{count} character(s)" | |||
msgid_plural "should be at least %{count} character(s)" | |||
msgstr[0] "" | |||
msgstr[1] "" | |||
msgid "should have at least %{count} item(s)" | |||
msgid_plural "should have at least %{count} item(s)" | |||
msgstr[0] "" | |||
msgstr[1] "" | |||
msgid "should be at most %{count} character(s)" | |||
msgid_plural "should be at most %{count} character(s)" | |||
msgstr[0] "" | |||
msgstr[1] "" | |||
msgid "should have at most %{count} item(s)" | |||
msgid_plural "should have at most %{count} item(s)" | |||
msgstr[0] "" | |||
msgstr[1] "" | |||
## From Ecto.Changeset.validate_number/3 | |||
msgid "must be less than %{number}" | |||
msgstr "" | |||
msgid "must be greater than %{number}" | |||
msgstr "" | |||
msgid "must be less than or equal to %{number}" | |||
msgstr "" | |||
msgid "must be greater than or equal to %{number}" | |||
msgstr "" | |||
msgid "must be equal to %{number}" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:505 | |||
#, elixir-format | |||
msgid "Account not found" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:339 | |||
#, elixir-format | |||
msgid "Already voted" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:359 | |||
#, elixir-format | |||
msgid "Bad request" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:426 | |||
#, elixir-format | |||
msgid "Can't delete object" | |||
msgstr "" | |||
#: lib/pleroma/web/controller_helper.ex:105 | |||
#: lib/pleroma/web/controller_helper.ex:111 | |||
#, elixir-format | |||
msgid "Can't display this activity" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:285 | |||
#, elixir-format | |||
msgid "Can't find user" | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/account_controller.ex:61 | |||
#, elixir-format | |||
msgid "Can't get favorites" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:438 | |||
#, elixir-format | |||
msgid "Can't like object" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/utils.ex:563 | |||
#, elixir-format | |||
msgid "Cannot post an empty status without attachments" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/utils.ex:511 | |||
#, elixir-format | |||
msgid "Comment must be up to %{max_size} characters" | |||
msgstr "" | |||
#: lib/pleroma/config/config_db.ex:191 | |||
#, elixir-format | |||
msgid "Config with params %{params} not found" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:181 | |||
#: lib/pleroma/web/common_api/common_api.ex:185 | |||
#, elixir-format | |||
msgid "Could not delete" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:231 | |||
#, elixir-format | |||
msgid "Could not favorite" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:453 | |||
#, elixir-format | |||
msgid "Could not pin" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:278 | |||
#, elixir-format | |||
msgid "Could not unfavorite" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:463 | |||
#, elixir-format | |||
msgid "Could not unpin" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:216 | |||
#, elixir-format | |||
msgid "Could not unrepeat" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:512 | |||
#: lib/pleroma/web/common_api/common_api.ex:521 | |||
#, elixir-format | |||
msgid "Could not update state" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:207 | |||
#, elixir-format | |||
msgid "Error." | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:106 | |||
#, elixir-format | |||
msgid "Invalid CAPTCHA" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:116 | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:568 | |||
#, elixir-format | |||
msgid "Invalid credentials" | |||
msgstr "" | |||
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:38 | |||
#, elixir-format | |||
msgid "Invalid credentials." | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:355 | |||
#, elixir-format | |||
msgid "Invalid indices" | |||
msgstr "" | |||
#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:29 | |||
#, elixir-format | |||
msgid "Invalid parameters" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/utils.ex:414 | |||
#, elixir-format | |||
msgid "Invalid password." | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:220 | |||
#, elixir-format | |||
msgid "Invalid request" | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:109 | |||
#, elixir-format | |||
msgid "Kocaptcha service unavailable" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:112 | |||
#, elixir-format | |||
msgid "Missing parameters" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/utils.ex:547 | |||
#, elixir-format | |||
msgid "No such conversation" | |||
msgstr "" | |||
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:388 | |||
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:414 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:456 | |||
#, elixir-format | |||
msgid "No such permission_group" | |||
msgstr "" | |||
#: lib/pleroma/plugs/uploaded_media.ex:84 | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:486 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11 | |||
#: lib/pleroma/web/feed/user_controller.ex:71 lib/pleroma/web/ostatus/ostatus_controller.ex:143 | |||
#, elixir-format | |||
msgid "Not found" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:331 | |||
#, elixir-format | |||
msgid "Poll's author can't vote" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 | |||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:37 lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:49 | |||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:50 lib/pleroma/web/mastodon_api/controllers/status_controller.ex:306 | |||
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 | |||
#, elixir-format | |||
msgid "Record not found" | |||
msgstr "" | |||
#: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:35 | |||
#: lib/pleroma/web/feed/user_controller.ex:77 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:36 | |||
#: lib/pleroma/web/ostatus/ostatus_controller.ex:149 | |||
#, elixir-format | |||
msgid "Something went wrong" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/activity_draft.ex:107 | |||
#, elixir-format | |||
msgid "The message visibility must be direct" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/utils.ex:573 | |||
#, elixir-format | |||
msgid "The status is over the character limit" | |||
msgstr "" | |||
#: lib/pleroma/plugs/ensure_public_or_authenticated_plug.ex:31 | |||
#, elixir-format | |||
msgid "This resource requires authentication." | |||
msgstr "" | |||
#: lib/pleroma/plugs/rate_limiter/rate_limiter.ex:206 | |||
#, elixir-format | |||
msgid "Throttled" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:356 | |||
#, elixir-format | |||
msgid "Too many choices" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:443 | |||
#, elixir-format | |||
msgid "Unhandled activity type" | |||
msgstr "" | |||
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:485 | |||
#, elixir-format | |||
msgid "You can't revoke your own admin status." | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:221 | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:308 | |||
#, elixir-format | |||
msgid "Your account is currently disabled" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:183 | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:331 | |||
#, elixir-format | |||
msgid "Your login is missing a confirmed e-mail address" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390 | |||
#, elixir-format | |||
msgid "can't read inbox of %{nickname} as %{as_nickname}" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:473 | |||
#, elixir-format | |||
msgid "can't update outbox of %{nickname} as %{as_nickname}" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:471 | |||
#, elixir-format | |||
msgid "conversation is already muted" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:314 | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:492 | |||
#, elixir-format | |||
msgid "error" | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:32 | |||
#, elixir-format | |||
msgid "mascots can only be images" | |||
msgstr "" | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:62 | |||
#, elixir-format | |||
msgid "not found" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:394 | |||
#, elixir-format | |||
msgid "Bad OAuth request." | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:115 | |||
#, elixir-format | |||
msgid "CAPTCHA already used" | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:112 | |||
#, elixir-format | |||
msgid "CAPTCHA expired" | |||
msgstr "" | |||
#: lib/pleroma/plugs/uploaded_media.ex:57 | |||
#, elixir-format | |||
msgid "Failed" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:410 | |||
#, elixir-format | |||
msgid "Failed to authenticate: %{message}." | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:441 | |||
#, elixir-format | |||
msgid "Failed to set up user account." | |||
msgstr "" | |||
#: lib/pleroma/plugs/oauth_scopes_plug.ex:38 | |||
#, elixir-format | |||
msgid "Insufficient permissions: %{permissions}." | |||
msgstr "" | |||
#: lib/pleroma/plugs/uploaded_media.ex:104 | |||
#, elixir-format | |||
msgid "Internal Error" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/fallback_controller.ex:22 | |||
#: lib/pleroma/web/oauth/fallback_controller.ex:29 | |||
#, elixir-format | |||
msgid "Invalid Username/Password" | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:118 | |||
#, elixir-format | |||
msgid "Invalid answer data" | |||
msgstr "" | |||
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:33 | |||
#, elixir-format | |||
msgid "Nodeinfo schema version not handled" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:172 | |||
#, elixir-format | |||
msgid "This action is outside the authorized scopes" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/fallback_controller.ex:14 | |||
#, elixir-format | |||
msgid "Unknown error, please check the details and try again." | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:119 | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:158 | |||
#, elixir-format | |||
msgid "Unlisted redirect_uri." | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:390 | |||
#, elixir-format | |||
msgid "Unsupported OAuth provider: %{provider}." | |||
msgstr "" | |||
#: lib/pleroma/uploaders/uploader.ex:72 | |||
#, elixir-format | |||
msgid "Uploader callback timeout" | |||
msgstr "" | |||
#: lib/pleroma/web/uploader_controller.ex:23 | |||
#, elixir-format | |||
msgid "bad request" | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:103 | |||
#, elixir-format | |||
msgid "CAPTCHA Error" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:290 | |||
#, elixir-format | |||
msgid "Could not add reaction emoji" | |||
msgstr "" | |||
#: lib/pleroma/web/common_api/common_api.ex:301 | |||
#, elixir-format | |||
msgid "Could not remove reaction emoji" | |||
msgstr "" | |||
#: lib/pleroma/web/twitter_api/twitter_api.ex:129 | |||
#, elixir-format | |||
msgid "Invalid CAPTCHA (Missing parameter: %{name})" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/list_controller.ex:92 | |||
#, elixir-format | |||
msgid "List not found" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:123 | |||
#, elixir-format | |||
msgid "Missing parameter: %{name}" | |||
msgstr "" | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:210 | |||
#: lib/pleroma/web/oauth/oauth_controller.ex:321 | |||
#, elixir-format | |||
msgid "Password reset is required" | |||
msgstr "" | |||
#: lib/pleroma/tests/auth_test_controller.ex:9 | |||
#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:6 lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:6 | |||
#: lib/pleroma/web/admin_api/controllers/config_controller.ex:6 lib/pleroma/web/admin_api/controllers/fallback_controller.ex:6 | |||
#: lib/pleroma/web/admin_api/controllers/invite_controller.ex:6 lib/pleroma/web/admin_api/controllers/media_proxy_cache_controller.ex:6 | |||
#: lib/pleroma/web/admin_api/controllers/oauth_app_controller.ex:6 lib/pleroma/web/admin_api/controllers/relay_controller.ex:6 | |||
#: lib/pleroma/web/admin_api/controllers/report_controller.ex:6 lib/pleroma/web/admin_api/controllers/status_controller.ex:6 | |||
#: lib/pleroma/web/controller_helper.ex:6 lib/pleroma/web/embed_controller.ex:6 | |||
#: lib/pleroma/web/fallback_redirect_controller.ex:6 lib/pleroma/web/feed/tag_controller.ex:6 | |||
#: lib/pleroma/web/feed/user_controller.ex:6 lib/pleroma/web/mailer/subscription_controller.ex:2 | |||
#: lib/pleroma/web/masto_fe_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/account_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/app_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/auth_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/conversation_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/custom_emoji_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/domain_block_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/filter_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/follow_request_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/instance_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/list_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/marker_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/mastodon_api_controller.ex:14 | |||
#: lib/pleroma/web/mastodon_api/controllers/media_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/notification_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/report_controller.ex:8 | |||
#: lib/pleroma/web/mastodon_api/controllers/scheduled_activity_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/search_controller.ex:6 | |||
#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:7 | |||
#: lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex:6 lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:6 | |||
#: lib/pleroma/web/media_proxy/media_proxy_controller.ex:6 lib/pleroma/web/mongooseim/mongoose_im_controller.ex:6 | |||
#: lib/pleroma/web/nodeinfo/nodeinfo_controller.ex:6 lib/pleroma/web/oauth/fallback_controller.ex:6 | |||
#: lib/pleroma/web/oauth/mfa_controller.ex:10 lib/pleroma/web/oauth/oauth_controller.ex:6 | |||
#: lib/pleroma/web/ostatus/ostatus_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/account_controller.ex:6 | |||
#: lib/pleroma/web/pleroma_api/controllers/chat_controller.ex:5 lib/pleroma/web/pleroma_api/controllers/conversation_controller.ex:6 | |||
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:2 lib/pleroma/web/pleroma_api/controllers/emoji_reaction_controller.ex:6 | |||
#: lib/pleroma/web/pleroma_api/controllers/mascot_controller.ex:6 lib/pleroma/web/pleroma_api/controllers/notification_controller.ex:6 | |||
#: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6 | |||
#: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 lib/pleroma/web/static_fe/static_fe_controller.ex:6 | |||
#: lib/pleroma/web/twitter_api/controllers/password_controller.ex:10 lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex:6 | |||
#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:6 lib/pleroma/web/twitter_api/twitter_api_controller.ex:6 | |||
#: lib/pleroma/web/uploader_controller.ex:6 lib/pleroma/web/web_finger/web_finger_controller.ex:6 | |||
#, elixir-format | |||
msgid "Security violation: OAuth scopes check was neither handled nor explicitly skipped." | |||
msgstr "" | |||
#: lib/pleroma/plugs/ensure_authenticated_plug.ex:28 | |||
#, elixir-format | |||
msgid "Two-factor authentication enabled, you must use a access token." | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:210 | |||
#, elixir-format | |||
msgid "Unexpected error occurred while adding file to pack." | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:138 | |||
#, elixir-format | |||
msgid "Unexpected error occurred while creating pack." | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:278 | |||
#, elixir-format | |||
msgid "Unexpected error occurred while removing file from pack." | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:250 | |||
#, elixir-format | |||
msgid "Unexpected error occurred while updating file in pack." | |||
msgstr "" | |||
#: lib/pleroma/web/pleroma_api/controllers/emoji_pack_controller.ex:179 | |||
#, elixir-format | |||
msgid "Unexpected error occurred while updating pack metadata." | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:61 | |||
#, elixir-format | |||
msgid "Web push subscription is disabled on this Pleroma instance" | |||
msgstr "" | |||
#: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:451 | |||
#, elixir-format | |||
msgid "You can't revoke your own admin/moderator status." | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:126 | |||
#, elixir-format | |||
msgid "authorization required for timeline view" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:24 | |||
#, elixir-format | |||
msgid "Access denied" | |||
msgstr "" | |||
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:282 | |||
#, elixir-format | |||
msgid "This API requires an authenticated user" | |||
msgstr "" | |||
#: lib/pleroma/plugs/user_is_admin_plug.ex:21 | |||
#, elixir-format | |||
msgid "User is not an admin." | |||
msgstr "" |
@@ -0,0 +1,13 @@ | |||
defmodule Pleroma.Repo.Migrations.RenameAwaitUpTimeoutInConnectionsPool do | |||
use Ecto.Migration | |||
def change do | |||
with %Pleroma.ConfigDB{} = config <- | |||
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: :connections_pool}), | |||
{timeout, value} when is_integer(timeout) <- Keyword.pop(config.value, :await_up_timeout) do | |||
config | |||
|> Ecto.Changeset.change(value: Keyword.put(value, :connect_timeout, timeout)) | |||
|> Pleroma.Repo.update() | |||
end | |||
end | |||
end |
@@ -0,0 +1,19 @@ | |||
defmodule Pleroma.Repo.Migrations.RenameTimeoutInPools do | |||
use Ecto.Migration | |||
def change do | |||
with %Pleroma.ConfigDB{} = config <- | |||
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: :pools}) do | |||
updated_value = | |||
Enum.map(config.value, fn {pool, pool_value} -> | |||
with {timeout, value} when is_integer(timeout) <- Keyword.pop(pool_value, :timeout) do | |||
{pool, Keyword.put(value, :recv_timeout, timeout)} | |||
end | |||
end) | |||
config | |||
|> Ecto.Changeset.change(value: updated_value) | |||
|> Pleroma.Repo.update() | |||
end | |||
end | |||
end |
@@ -0,0 +1,19 @@ | |||
defmodule Pleroma.Repo.Migrations.RemoveCronStatsWorkerFromObanConfig do | |||
use Ecto.Migration | |||
def change do | |||
with %Pleroma.ConfigDB{} = config <- | |||
Pleroma.ConfigDB.get_by_params(%{group: :pleroma, key: Oban}), | |||
crontab when is_list(crontab) <- config.value[:crontab], | |||
index when is_integer(index) <- | |||
Enum.find_index(crontab, fn {_, worker} -> | |||
worker == Pleroma.Workers.Cron.StatsWorker | |||
end) do | |||
updated_value = Keyword.put(config.value, :crontab, List.delete_at(crontab, index)) | |||
config | |||
|> Ecto.Changeset.change(value: updated_value) | |||
|> Pleroma.Repo.update() | |||
end | |||
end | |||
end |
@@ -1 +1 @@ | |||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.77b1644622e3bae24b6b.css rel=stylesheet><link href=/static/fontello.1598361006087.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.bc5812c087f5dbcb914d.js></script><script type=text/javascript src=/static/js/app.154c25316542278028a6.js></script></body></html> | |||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.77b1644622e3bae24b6b.css rel=stylesheet><link href=/static/fontello.1599568314856.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.90c4af83c1ae68f4cd95.js></script><script type=text/javascript src=/static/js/app.55d173dc5e39519aa518.js></script></body></html> |
@@ -1,11 +1,11 @@ | |||
@font-face { | |||
font-family: "Icons"; | |||
src: url("./font/fontello.1598361006087.eot"); | |||
src: url("./font/fontello.1598361006087.eot") format("embedded-opentype"), | |||
url("./font/fontello.1598361006087.woff2") format("woff2"), | |||
url("./font/fontello.1598361006087.woff") format("woff"), | |||
url("./font/fontello.1598361006087.ttf") format("truetype"), | |||
url("./font/fontello.1598361006087.svg") format("svg"); | |||
src: url("./font/fontello.1599568314856.eot"); | |||
src: url("./font/fontello.1599568314856.eot") format("embedded-opentype"), | |||
url("./font/fontello.1599568314856.woff2") format("woff2"), | |||
url("./font/fontello.1599568314856.woff") format("woff"), | |||
url("./font/fontello.1599568314856.ttf") format("truetype"), | |||
url("./font/fontello.1599568314856.svg") format("svg"); | |||
font-weight: normal; | |||
font-style: normal; | |||
} |
@@ -1 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/10.1c5cd5fbe554eca63dfe.js","sourceRoot":""} | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/10.46fbbdfaf0d4800f349b.js","sourceRoot":""} |
@@ -1 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/12.6619e0b2f854637e76d4.js","sourceRoot":""} | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/12.b3bf0bc313861d6ec36b.js","sourceRoot":""} |
@@ -1 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/13.c843797f3e374f0e3e1a.js","sourceRoot":""} | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/13.adb8a942514d735722c4.js","sourceRoot":""} |
@@ -1 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/14.71f8caca49093a99e871.js","sourceRoot":""} | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/14.d015d9b2ea16407e389c.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/18.94946caca48930c224c7.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/18.b29eedabe76445fe94b8.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/19.233c81ac2c28d55e9f13.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/19.ed1cd5db596618779f03.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/20.6d311b830d8ac672729f.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/20.818c38d27369c3a4d677.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/23.2c5f0fd2f2acd04592e8.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/23.a57a7845cc20fafd06d1.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/25.365514e44606a895ab50.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/25.5a9efe20e3ae1352e6d2.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/28.9eb3e783aeba24c84f0a.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/28.e0f9f164e0bfd890dc61.js","sourceRoot":""} |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/30.a9377272337674f2dd05.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/30.fce58be0b52ca3e32fa4.js","sourceRoot":""} |
@@ -1 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/8.5f48d6f0cbed548baf0f.js","sourceRoot":""} | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/8.636322a87bb10a1754f8.js","sourceRoot":""} |
@@ -1 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/9.a95fcd286ba2c9050c4d.js","sourceRoot":""} | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/9.6010dbcce7b4d7c05a18.js","sourceRoot":""} |