Merge branch 'develop' of https://git.pleroma.social/pleroma/pleroma into develop

This commit is contained in:
sadposter 2020-02-20 13:50:56 +00:00
commit fae0d4ba9d
280 changed files with 2308 additions and 3173 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
*.ex diff=elixir
*.exs diff=elixir

View file

@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Breaking:** attachment links (`config :pleroma, :instance, no_attachment_links` and `config :pleroma, Pleroma.Upload, link_name`) disabled by default - **Breaking:** attachment links (`config :pleroma, :instance, no_attachment_links` and `config :pleroma, Pleroma.Upload, link_name`) disabled by default
- **Breaking:** OAuth: defaulted `[:auth, :enforce_oauth_admin_scope_usage]` setting to `true` which demands `admin` OAuth scope to perform admin actions (in addition to `is_admin` flag on User); make sure to use bundled or newer versions of AdminFE & PleromaFE to access admin / moderator features. - **Breaking:** OAuth: defaulted `[:auth, :enforce_oauth_admin_scope_usage]` setting to `true` which demands `admin` OAuth scope to perform admin actions (in addition to `is_admin` flag on User); make sure to use bundled or newer versions of AdminFE & PleromaFE to access admin / moderator features.
- **Breaking:** Dynamic configuration has been rearchitected. The `:pleroma, :instance, dynamic_configuration` setting has been replaced with `config :pleroma, configurable_from_database`. Please backup your configuration to a file and run the migration task to ensure consistency with the new schema. - **Breaking:** Dynamic configuration has been rearchitected. The `:pleroma, :instance, dynamic_configuration` setting has been replaced with `config :pleroma, configurable_from_database`. Please backup your configuration to a file and run the migration task to ensure consistency with the new schema.
- **Breaking:** `:instance, no_attachment_links` has been replaced with `:instance, attachment_links` which still takes a boolean value but doesn't use double negative language.
- Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings) - Replaced [pleroma_job_queue](https://git.pleroma.social/pleroma/pleroma_job_queue) and `Pleroma.Web.Federator.RetryQueue` with [Oban](https://github.com/sorentwo/oban) (see [`docs/config.md`](docs/config.md) on migrating customized worker / retry settings)
- Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler - Introduced [quantum](https://github.com/quantum-elixir/quantum-core) job scheduler
- Enabled `:instance, extended_nickname_format` in the default config - Enabled `:instance, extended_nickname_format` in the default config
@ -37,6 +38,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>
- **Breaking** EmojiReactions: Change endpoints and responses to align with Mastodon
- **Breaking** Admin API: `PATCH /api/pleroma/admin/users/:nickname/force_password_reset` is now `PATCH /api/pleroma/admin/users/force_password_reset` (accepts `nicknames` array in the request body) - **Breaking** Admin API: `PATCH /api/pleroma/admin/users/:nickname/force_password_reset` is now `PATCH /api/pleroma/admin/users/force_password_reset` (accepts `nicknames` array in the request body)
- **Breaking:** Admin API: Return link alongside with token on password reset - **Breaking:** Admin API: Return link alongside with token on password reset
- **Breaking:** Admin API: `PUT /api/pleroma/admin/reports/:id` is now `PATCH /api/pleroma/admin/reports`, see admin_api.md for details - **Breaking:** Admin API: `PUT /api/pleroma/admin/reports/:id` is now `PATCH /api/pleroma/admin/reports`, see admin_api.md for details
@ -70,7 +72,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- User notification settings: Add `privacy_option` option. - User notification settings: Add `privacy_option` option.
- Support for custom Elixir modules (such as MRF policies) - Support for custom Elixir modules (such as MRF policies)
- User settings: Add _This account is a_ option. - User settings: Add _This account is a_ option.
- A new users admin digest email
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`). - OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
- Add an option `authorized_fetch_mode` to require HTTP signatures for AP fetches.
<details> <details>
<summary>API Changes</summary> <summary>API Changes</summary>

View file

@ -51,20 +51,6 @@
telemetry_event: [Pleroma.Repo.Instrumenter], telemetry_event: [Pleroma.Repo.Instrumenter],
migration_lock: nil migration_lock: nil
scheduled_jobs =
with digest_config <- Application.get_env(:pleroma, :email_notifications)[:digest],
true <- digest_config[:active] do
[{digest_config[:schedule], {Pleroma.Daemons.DigestEmailDaemon, :perform, []}}]
else
_ -> []
end
config :pleroma, Pleroma.Scheduler,
global: true,
overlap: true,
timezone: :utc,
jobs: scheduled_jobs
config :pleroma, Pleroma.Captcha, config :pleroma, Pleroma.Captcha,
enabled: true, enabled: true,
seconds_valid: 300, seconds_valid: 300,
@ -256,7 +242,7 @@
staff_transparency: [], staff_transparency: [],
autofollowed_nicknames: [], autofollowed_nicknames: [],
max_pinned_statuses: 1, max_pinned_statuses: 1,
no_attachment_links: true, attachment_links: false,
welcome_user_nickname: nil, welcome_user_nickname: nil,
welcome_message: nil, welcome_message: nil,
max_report_comment_size: 1000, max_report_comment_size: 1000,
@ -341,7 +327,8 @@
unfollow_blocked: true, unfollow_blocked: true,
outgoing_blocks: true, outgoing_blocks: true,
follow_handshake_timeout: 500, follow_handshake_timeout: 500,
sign_object_fetches: true sign_object_fetches: true,
authorized_fetch_mode: false
config :pleroma, :streamer, config :pleroma, :streamer,
workers: 3, workers: 3,
@ -495,7 +482,15 @@
transmogrifier: 20, transmogrifier: 20,
scheduled_activities: 10, scheduled_activities: 10,
background: 5, background: 5,
attachments_cleanup: 5 attachments_cleanup: 5,
new_users_digest: 1
],
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}
] ]
config :pleroma, :workers, config :pleroma, :workers,
@ -569,6 +564,8 @@
text_muted_color: "#b9b9ba" text_muted_color: "#b9b9ba"
} }
config :pleroma, Pleroma.Emails.NewUsersDigestEmail, enabled: false
config :prometheus, Pleroma.Web.Endpoint.MetricsExporter, path: "/api/pleroma/app_metrics" config :prometheus, Pleroma.Web.Endpoint.MetricsExporter, path: "/api/pleroma/app_metrics"
config :pleroma, Pleroma.ScheduledActivity, config :pleroma, Pleroma.ScheduledActivity,
@ -579,7 +576,6 @@
config :pleroma, :email_notifications, config :pleroma, :email_notifications,
digest: %{ digest: %{
active: false, active: false,
schedule: "0 0 * * 0",
interval: 7, interval: 7,
inactivity_threshold: 7 inactivity_threshold: 7
} }
@ -587,8 +583,7 @@
config :pleroma, :oauth2, config :pleroma, :oauth2,
token_expires_in: 600, token_expires_in: 600,
issue_new_refresh_token: true, issue_new_refresh_token: true,
clean_expired_tokens: false, clean_expired_tokens: false
clean_expired_tokens_interval: 86_400_000
config :pleroma, :database, rum_enabled: false config :pleroma, :database, rum_enabled: false
@ -623,7 +618,6 @@
config :pleroma, configurable_from_database: false config :pleroma, configurable_from_database: false
config :swarm, node_blacklist: [~r/myhtml_.*$/]
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs" import_config "#{Mix.env()}.exs"

View file

@ -101,7 +101,7 @@
%{ %{
key: :versions, key: :versions,
type: {:list, :atom}, type: {:list, :atom},
description: "List of TLS version to use", description: "List of TLS versions to use",
suggestions: [:tlsv1, ":tlsv1.1", ":tlsv1.2"] suggestions: [:tlsv1, ":tlsv1.1", ":tlsv1.2"]
} }
] ]
@ -534,7 +534,8 @@
%{ %{
key: :description, key: :description,
type: :string, type: :string,
description: "The instance's description, can be seen in nodeinfo and /api/v1/instance", description:
"The instance's description. It can be seen in nodeinfo and `/api/v1/instance`",
suggestions: [ suggestions: [
"Very cool instance" "Very cool instance"
] ]
@ -637,22 +638,24 @@
%{ %{
key: :registrations_open, key: :registrations_open,
type: :boolean, type: :boolean,
description: "Enable registrations for anyone, invitations can be enabled when `false`" description:
"Enable registrations for anyone. Invitations require this setting to be disabled."
}, },
%{ %{
key: :invites_enabled, key: :invites_enabled,
type: :boolean, type: :boolean,
description: "Enable user invitations for admins (depends on `registrations_open: false`)" description:
"Enable user invitations for admins (depends on `registrations_open` being disabled)."
}, },
%{ %{
key: :account_activation_required, key: :account_activation_required,
type: :boolean, type: :boolean,
description: "Require users to confirm their emails before signing in" description: "Require users to confirm their emails before signing in."
}, },
%{ %{
key: :federating, key: :federating,
type: :boolean, type: :boolean,
description: "Enable federation with other instances" description: "Enable federation with other instances."
}, },
%{ %{
key: :federation_incoming_replies_max_depth, key: :federation_incoming_replies_max_depth,
@ -761,14 +764,14 @@
key: :extended_nickname_format, key: :extended_nickname_format,
type: :boolean, type: :boolean,
description: description:
"Set to `true` to use extended local nicknames format (allows underscores/dashes)." <> "Enable to use extended local nicknames format (allows underscores/dashes)." <>
" This will break federation with older software for theses nicknames." " This will break federation with older software for theses nicknames."
}, },
%{ %{
key: :cleanup_attachments, key: :cleanup_attachments,
type: :boolean, type: :boolean,
description: """ description: """
"Set to `true` to remove associated attachments when status is removed. Enable to remove associated attachments when status is removed.
This will not affect duplicates and attachments without status. This will not affect duplicates and attachments without status.
Enabling this will increase load to database when deleting statuses on larger instances. Enabling this will increase load to database when deleting statuses on larger instances.
""" """
@ -796,10 +799,9 @@
] ]
}, },
%{ %{
key: :no_attachment_links, key: :attachment_links,
type: :boolean, type: :boolean,
description: description: "Enable to automatically add attachment link text to statuses"
"Set to `true` to disable automatically adding attachment link text to statuses"
}, },
%{ %{
key: :welcome_message, key: :welcome_message,
@ -830,14 +832,14 @@
key: :safe_dm_mentions, key: :safe_dm_mentions,
type: :boolean, type: :boolean,
description: description:
"If set to `true`, only mentions at the beginning of a post will be used to address people in direct messages." <> "If enabled, only mentions at the beginning of a post will be used to address people in direct messages." <>
" This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\")." <> " This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\")." <>
" Default: `false`" " Default: disabled"
}, },
%{ %{
key: :healthcheck, key: :healthcheck,
type: :boolean, type: :boolean,
description: "If set to `true`, system data will be shown on /api/pleroma/healthcheck" description: "If enabled, system data will be shown on `/api/pleroma/healthcheck`"
}, },
%{ %{
key: :remote_post_retention_days, key: :remote_post_retention_days,
@ -867,7 +869,7 @@
%{ %{
key: :skip_thread_containment, key: :skip_thread_containment,
type: :boolean, type: :boolean,
description: "Skip filter out broken threads. Default: `true`" description: "Skip filtering out broken threads. Default: enabled"
}, },
%{ %{
key: :limit_to_local_content, key: :limit_to_local_content,
@ -1159,17 +1161,15 @@
key: :alwaysShowSubjectInput, key: :alwaysShowSubjectInput,
label: "Always show subject input", label: "Always show subject input",
type: :boolean, type: :boolean,
description: "When set to `false`, auto-hide the subject field when it's empty" description: "When disabled, auto-hide the subject field if it's empty"
}, },
%{ %{
key: :logoMask, key: :logoMask,
label: "Logo mask", label: "Logo mask",
type: :boolean, type: :boolean,
description: description:
"By default it assumes logo used will be monochrome-with-alpha one, this is done to be compatible with both light and dark themes, " <> "By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. " <>
"so that white logo designed with dark theme in mind won't be invisible over light theme, this is done via CSS3 Masking. " <> "If you want a colorful logo you must disable logoMask."
"Basically - it will take alpha channel of the image and fill non-transparent areas of it with solid color. " <>
"If you really want colorful logo - it can be done by setting logoMask to false."
}, },
%{ %{
key: :logoMargin, key: :logoMargin,
@ -1183,13 +1183,13 @@
%{ %{
key: :stickers, key: :stickers,
type: :boolean, type: :boolean,
description: "Enables/disables stickers." description: "Enables stickers."
}, },
%{ %{
key: :enableEmojiPicker, key: :enableEmojiPicker,
label: "Emoji picker", label: "Emoji picker",
type: :boolean, type: :boolean,
description: "Enables/disables emoji picker." description: "Enables emoji picker."
} }
] ]
}, },
@ -1297,14 +1297,14 @@
%{ %{
key: :media_removal, key: :media_removal,
type: {:list, :string}, type: {:list, :string},
description: "List of instances to remove medias from", description: "List of instances to strip media attachments from",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
key: :media_nsfw, key: :media_nsfw,
label: "Media NSFW", label: "Media NSFW",
type: {:list, :string}, type: {:list, :string},
description: "List of instances to put medias as NSFW (sensitive) from", description: "List of instances to tag all media as NSFW (sensitive) from",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
@ -1423,21 +1423,21 @@
key: :reject, key: :reject,
type: [:string, :regex], type: [:string, :regex],
description: description:
"A list of patterns which result in message being rejected, each pattern can be a string or a regular expression.", "A list of patterns which result in message being rejected. Each pattern can be a string or a regular expression.",
suggestions: ["foo", ~r/foo/iu] suggestions: ["foo", ~r/foo/iu]
}, },
%{ %{
key: :federated_timeline_removal, key: :federated_timeline_removal,
type: [:string, :regex], type: [:string, :regex],
description: description:
"A list of patterns which result in message being removed from federated timelines (a.k.a unlisted), each pattern can be a string or a regular expression.", "A list of patterns which result in message being removed from federated timelines (a.k.a unlisted). Each pattern can be a string or a regular expression.",
suggestions: ["foo", ~r/foo/iu] suggestions: ["foo", ~r/foo/iu]
}, },
%{ %{
key: :replace, key: :replace,
type: [{:tuple, :string, :string}, {:tuple, :regex, :string}], type: [{:tuple, :string, :string}, {:tuple, :regex, :string}],
description: description:
"A list of tuples containing {pattern, replacement}, pattern can be a string or a regular expression.", "A list of tuples containing {pattern, replacement}. Each pattern can be a string or a regular expression.",
suggestions: [{"foo", "bar"}, {~r/foo/iu, "bar"}] suggestions: [{"foo", "bar"}, {~r/foo/iu, "bar"}]
} }
] ]
@ -1452,7 +1452,7 @@
%{ %{
key: :actors, key: :actors,
type: {:list, :string}, type: {:list, :string},
description: "A list of actors, for which to drop any posts mentioning", description: "A list of actors for which any post mentioning them will be dropped.",
suggestions: ["actor1", "actor2"] suggestions: ["actor1", "actor2"]
} }
] ]
@ -1856,9 +1856,8 @@
type: :string, type: :string,
description: description:
"A mailto link for the administrative contact." <> "A mailto link for the administrative contact." <>
" It's best if this email is not a personal email address, but rather a group email so that if a person leaves an organization," <> " It's best if this email is not a personal email address, but rather a group email to the instance moderation team.",
" is unavailable for an extended period, or otherwise can't respond, someone else on the list can.", suggestions: ["mailto:moderators@pleroma.com"]
suggestions: ["Subject"]
}, },
%{ %{
key: :public_key, key: :public_key,
@ -1925,7 +1924,7 @@
key: :admin_token, key: :admin_token,
type: :string, type: :string,
description: "Token", description: "Token",
suggestions: ["some_random_token"] suggestions: ["We recommend a secure random string or UUID"]
} }
] ]
}, },
@ -1987,6 +1986,7 @@
"Background jobs queues (keys: queues, values: max numbers of concurrent jobs)", "Background jobs queues (keys: queues, values: max numbers of concurrent jobs)",
suggestions: [ suggestions: [
activity_expiration: 10, activity_expiration: 10,
attachments_cleanup: 5,
background: 5, background: 5,
federator_incoming: 50, federator_incoming: 50,
federator_outgoing: 50, federator_outgoing: 50,
@ -2002,6 +2002,12 @@
description: "Activity expiration queue", description: "Activity expiration queue",
suggestions: [10] suggestions: [10]
}, },
%{
key: :attachments_cleanup,
type: :integer,
description: "Attachment deletion queue",
suggestions: [5]
},
%{ %{
key: :background, key: :background,
type: :integer, type: :integer,
@ -2086,7 +2092,7 @@
key: :unfurl_nsfw, key: :unfurl_nsfw,
label: "Unfurl NSFW", label: "Unfurl NSFW",
type: :boolean, type: :boolean,
description: "If set to `true` NSFW attachments will be shown in previews" description: "When enabled NSFW attachments will be shown in previews"
} }
] ]
}, },
@ -2100,7 +2106,7 @@
%{ %{
key: :enabled, key: :enabled,
type: :boolean, type: :boolean,
description: "Enables/disables RichMedia." description: "Enables RichMedia parsing of URLs."
}, },
%{ %{
key: :ignore_hosts, key: :ignore_hosts,
@ -2146,8 +2152,7 @@
%{ %{
key: :enabled, key: :enabled,
type: :boolean, type: :boolean,
description: description: "Fetch posts when a new user is federated with"
"If enabled, when a new user is federated with, fetch some of their latest posts"
}, },
%{ %{
key: :pages, key: :pages,
@ -2166,13 +2171,13 @@
%{ %{
key: :class, key: :class,
type: [:string, false], type: [:string, false],
description: "Specify the class to be added to the generated link. `False` to clear", description: "Specify the class to be added to the generated link. Disable to clear",
suggestions: ["auto-linker", false] suggestions: ["auto-linker", false]
}, },
%{ %{
key: :rel, key: :rel,
type: [:string, false], type: [:string, false],
description: "Override the rel attribute. `False` to clear", description: "Override the rel attribute. Disable to clear",
suggestions: ["ugc", "noopener noreferrer", false] suggestions: ["ugc", "noopener noreferrer", false]
}, },
%{ %{
@ -2282,7 +2287,7 @@
key: :ssl, key: :ssl,
label: "SSL", label: "SSL",
type: :boolean, type: :boolean,
description: "`True` to use SSL, usually implies the port 636" description: "Enable to use SSL, usually implies the port 636"
}, },
%{ %{
key: :sslopts, key: :sslopts,
@ -2309,7 +2314,7 @@
key: :tls, key: :tls,
label: "TLS", label: "TLS",
type: :boolean, type: :boolean,
description: "`True` to start TLS, usually implies the port 389" description: "Enable to use STARTTLS, usually implies the port 389"
}, },
%{ %{
key: :tlsopts, key: :tlsopts,
@ -2358,8 +2363,8 @@
type: :boolean, type: :boolean,
description: description:
"OAuth admin scope requirement toggle. " <> "OAuth admin scope requirement toggle. " <>
"If `true`, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token " <> "If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token " <>
"(client app must support admin scopes). If `false` and token doesn't have admin scope(s)," <> "(client app must support admin scopes). If disabled and token doesn't have admin scope(s)," <>
"`is_admin` user flag grants access to admin-specific actions." "`is_admin` user flag grants access to admin-specific actions."
}, },
%{ %{
@ -2381,7 +2386,7 @@
key: :oauth_consumer_strategies, key: :oauth_consumer_strategies,
type: {:list, :string}, type: {:list, :string},
description: description:
"The list of enabled OAuth consumer strategies; by default it's set by OAUTH_CONSUMER_STRATEGIES environment variable." <> "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable." <>
" Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\"" <> " Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\"" <>
" (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_<strategy>).", " (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_<strategy>).",
suggestions: ["twitter", "keycloak:ueberauth_keycloak_strategy"] suggestions: ["twitter", "keycloak:ueberauth_keycloak_strategy"]
@ -2497,6 +2502,20 @@
} }
] ]
}, },
%{
group: :pleroma,
key: Pleroma.Emails.NewUsersDigestEmail,
type: :group,
description: "New users admin email digest",
children: [
%{
key: :enabled,
type: :boolean,
description: "enables new users admin digest email when `true`",
suggestions: [false]
}
]
},
%{ %{
group: :pleroma, group: :pleroma,
key: :oauth2, key: :oauth2,
@ -2518,14 +2537,7 @@
%{ %{
key: :clean_expired_tokens, key: :clean_expired_tokens,
type: :boolean, type: :boolean,
description: "Enable a background job to clean expired oauth tokens. Default: `false`." description: "Enable a background job to clean expired oauth tokens. Default: disabled."
},
%{
key: :clean_expired_tokens_interval,
type: :integer,
description:
"Interval to run the job to clean expired tokens. Default: 86_400_000 (24 hours).",
suggestions: [86_400_000]
} }
] ]
}, },
@ -2585,7 +2597,7 @@
%{ %{
key: :rum_enabled, key: :rum_enabled,
type: :boolean, type: :boolean,
description: "If RUM indexes should be used. Default: `false`" description: "If RUM indexes should be used. Default: disabled"
} }
] ]
}, },
@ -2971,7 +2983,7 @@
%{ %{
key: :enabled, key: :enabled,
type: :boolean, type: :boolean,
description: "Enable/disable the plug. Default: `false`." description: "Enable/disable the plug. Default: disabled."
}, },
%{ %{
key: :headers, key: :headers,
@ -3025,7 +3037,7 @@
%{ %{
key: :enabled, key: :enabled,
type: :boolean, type: :boolean,
description: "Enables the rendering of static HTML. Defaults to `false`." description: "Enables the rendering of static HTML. Default: disabled."
} }
] ]
}, },
@ -3101,7 +3113,7 @@
key: :configurable_from_database, key: :configurable_from_database,
type: :boolean, type: :boolean,
description: description:
"Allow transferring configuration to DB with the subsequent customization from Admin api. Defaults to `false`" "Allow transferring configuration to DB with the subsequent customization from Admin api. Default: disabled"
} }
] ]
} }

View file

@ -66,11 +66,8 @@
config :pleroma, Oban, config :pleroma, Oban,
queues: false, queues: false,
prune: :disabled prune: :disabled,
crontab: false
config :pleroma, Pleroma.Scheduler,
jobs: [],
global: false
config :pleroma, Pleroma.ScheduledActivity, config :pleroma, Pleroma.ScheduledActivity,
daily_user_limit: 2, daily_user_limit: 2,
@ -97,6 +94,8 @@
config :pleroma, :modules, runtime_dir: "test/fixtures/modules" config :pleroma, :modules, runtime_dir: "test/fixtures/modules"
config :pleroma, Pleroma.Emails.NewUsersDigestEmail, enabled: true
if File.exists?("./config/test.secret.exs") do if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs" import_config "test.secret.exs"
else else

View file

@ -682,6 +682,8 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
### Get list of merged default settings with saved in database. ### Get list of merged default settings with saved in database.
*If `need_reboot` flag exists in response, instance must be restarted, so reboot time settings can take effect.*
**Only works when configuration from database is enabled.** **Only works when configuration from database is enabled.**
- Params: - Params:
@ -692,20 +694,24 @@ Note: Available `:permission_group` is currently moderator and admin. 404 is ret
```json ```json
{ {
configs: [ "configs": [
{ {
"group": ":pleroma", "group": ":pleroma",
"key": "Pleroma.Upload", "key": "Pleroma.Upload",
"value": [] "value": []
} }
] ],
"need_reboot": true
} }
``` ```
need_reboot - *optional*, if were changed reboot time settings.
## `POST /api/pleroma/admin/config` ## `POST /api/pleroma/admin/config`
### Update config settings ### Update config settings
*If `need_reboot` flag exists in response, instance must be restarted, so reboot time settings can take effect.*
**Only works when configuration from database is enabled.** **Only works when configuration from database is enabled.**
Some modifications are necessary to save the config settings correctly: Some modifications are necessary to save the config settings correctly:
@ -793,7 +799,7 @@ config :quack,
``` ```
```json ```json
{ {
configs: [ "configs": [
{"group": ":quack", "key": ":level", "value": ":debug"}, {"group": ":quack", "key": ":level", "value": ":debug"},
{"group": ":quack", "key": ":meta", "value": [":all"]}, {"group": ":quack", "key": ":meta", "value": [":all"]},
... ...
@ -804,7 +810,7 @@ config :quack,
```json ```json
{ {
configs: [ "configs": [
{ {
"group": ":pleroma", "group": ":pleroma",
"key": "Pleroma.Upload", "key": "Pleroma.Upload",
@ -836,15 +842,17 @@ config :quack,
- 400 Bad Request `"To use this endpoint you need to enable configuration from database."` - 400 Bad Request `"To use this endpoint you need to enable configuration from database."`
```json ```json
{ {
configs: [ "configs": [
{ {
"group": ":pleroma", "group": ":pleroma",
"key": "Pleroma.Upload", "key": "Pleroma.Upload",
"value": [...] "value": [...]
} }
] ],
"need_reboot": true
} }
``` ```
need_reboot - *optional*, if were changed reboot time settings.
## ` GET /api/pleroma/admin/config/descriptions` ## ` GET /api/pleroma/admin/config/descriptions`

View file

@ -29,7 +29,7 @@ Has these additional fields under the `pleroma` object:
- `spoiler_text`: a map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain` - `spoiler_text`: a map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`
- `expires_at`: a datetime (iso8601) that states when the post will expire (be deleted automatically), or empty if the post won't expire - `expires_at`: a datetime (iso8601) that states when the post will expire (be deleted automatically), or empty if the post won't expire
- `thread_muted`: true if the thread the post belongs to is muted - `thread_muted`: true if the thread the post belongs to is muted
- `emoji_reactions`: A list with emoji / reaction maps. The format is `{emoji: "☕", count: 1, reacted: true}`. Contains no information about the reacting users, for that use the `emoji_reactions_by` endpoint. - `emoji_reactions`: A list with emoji / reaction maps. The format is `{name: "☕", count: 1, me: true}`. Contains no information about the reacting users, for that use the `/statuses/:id/reactions` endpoint.
## Attachments ## Attachments
@ -88,6 +88,9 @@ Behavior has changed:
- `/api/v1/accounts/search`: Does not require authentication - `/api/v1/accounts/search`: Does not require authentication
## Search (global)
Unlisted posts are available in search results, they are considered to be public posts that shouldn't be shown in local/federated timeline.
## Notifications ## Notifications

View file

@ -432,21 +432,21 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
Emoji reactions work a lot like favourites do. They make it possible to react to a post with a single emoji character. Emoji reactions work a lot like favourites do. They make it possible to react to a post with a single emoji character.
## `POST /api/v1/pleroma/statuses/:id/react_with_emoji` ## `PUT /api/v1/pleroma/statuses/:id/reactions/:emoji`
### React to a post with a unicode emoji ### React to a post with a unicode emoji
* Method: `POST` * Method: `PUT`
* Authentication: required * Authentication: required
* Params: `emoji`: A single character unicode emoji * Params: `emoji`: A single character unicode emoji
* Response: JSON, the status. * Response: JSON, the status.
## `POST /api/v1/pleroma/statuses/:id/unreact_with_emoji` ## `DELETE /api/v1/pleroma/statuses/:id/reactions/:emoji`
### Remove a reaction to a post with a unicode emoji ### Remove a reaction to a post with a unicode emoji
* Method: `POST` * Method: `DELETE`
* Authentication: required * Authentication: required
* Params: `emoji`: A single character unicode emoji * Params: `emoji`: A single character unicode emoji
* Response: JSON, the status. * Response: JSON, the status.
## `GET /api/v1/pleroma/statuses/:id/emoji_reactions_by` ## `GET /api/v1/pleroma/statuses/:id/reactions`
### Get an object of emoji to account mappings with accounts that reacted to the post ### Get an object of emoji to account mappings with accounts that reacted to the post
* Method: `GET` * Method: `GET`
* Authentication: optional * Authentication: optional
@ -455,7 +455,7 @@ Emoji reactions work a lot like favourites do. They make it possible to react to
* Example Response: * Example Response:
```json ```json
[ [
{"emoji": "😀", "count": 2, "reacted": true, "accounts": [{"id" => "xyz.."...}, {"id" => "zyx..."}]}, {"name": "😀", "count": 2, "me": true, "accounts": [{"id" => "xyz.."...}, {"id" => "zyx..."}]},
{"emoji": "☕", "count": 1, "reacted": false, "accounts": [{"id" => "abc..."}]} {"name": "☕", "count": 1, "me": false, "accounts": [{"id" => "abc..."}]}
] ]
``` ```

View file

@ -1,17 +1,35 @@
# Backup/Restore your instance # Backup/Restore/Move/Remove your instance
## Backup ## Backup
1. Stop the Pleroma service. 1. Stop the Pleroma service.
2. Go to the working directory of Pleroma (default is `/opt/pleroma`) 2. Go to the working directory of Pleroma (default is `/opt/pleroma`)
3. Run `sudo -Hu postgres pg_dump -d <pleroma_db> --format=custom -f </path/to/backup_location/pleroma.pgdump>` 3. Run `sudo -Hu postgres pg_dump -d <pleroma_db> --format=custom -f </path/to/backup_location/pleroma.pgdump>` (make sure the postgres user has write access to the destination file)
4. Copy `pleroma.pgdump`, `config/prod.secret.exs` and the `uploads` folder to your backup destination. If you have other modifications, copy those changes too. 4. Copy `pleroma.pgdump`, `config/prod.secret.exs` and the `uploads` folder to your backup destination. If you have other modifications, copy those changes too.
5. Restart the Pleroma service. 5. Restart the Pleroma service.
## Restore ## Restore/Move
1. Stop the Pleroma service. 1. Optionally reinstall Pleroma (either on the same server or on another server if you want to move servers). Try to use the same database name.
2. Go to the working directory of Pleroma (default is `/opt/pleroma`) 2. Stop the Pleroma service.
3. Copy the above mentioned files back to their original position. 3. Go to the working directory of Pleroma (default is `/opt/pleroma`)
4. Run `sudo -Hu postgres pg_restore -d <pleroma_db> -v -1 </path/to/backup_location/pleroma.pgdump>` 4. Copy the above mentioned files back to their original position.
5. Restart the Pleroma service. 5. Drop the existing database and recreate an empty one `sudo -Hu postgres psql -c 'DROP DATABASE <pleroma_db>;';` `sudo -Hu postgres psql -c 'CREATE DATABASE <pleroma_db>;';`
6. Run `sudo -Hu postgres pg_restore -d <pleroma_db> -v -1 </path/to/backup_location/pleroma.pgdump>`
7. If you installed a newer Pleroma version, you should run `mix ecto.migrate`[^1]. This task performs database migrations, if there were any.
8. Restart the Pleroma service.
[^1]: Prefix with `MIX_ENV=prod` to run it using the production config file.
## Remove
1. Optionally you can remove the users of your instance. This will trigger delete requests for their accounts and posts. Note that this is 'best effort' and doesn't mean that all traces of your instance will be gone from the fediverse.
* You can do this from the admin-FE where you can select all local users and delete the accounts using the *Moderate multiple users* dropdown.
* You can also list local users and delete them individualy using the CLI tasks for [Managing users](./CLI_tasks/user.md).
2. Stop the Pleroma service `systemctl stop pleroma`
3. Disable pleroma from systemd `systemctl disable pleroma`
4. Remove the files and folders you created during installation (see installation guide). This includes the pleroma, nginx and systemd files and folders.
5. Reload nginx now that the configuration is removed `systemctl reload nginx`
6. Remove the database and database user `sudo -Hu postgres psql -c 'DROP DATABASE <pleroma_db>;';` `sudo -Hu postgres psql -c 'DROP USER <pleroma_db>;';`
7. Remove the system user `userdel pleroma`
8. Remove the dependencies that you don't need anymore (see installation guide). Make sure you don't remove packages that are still needed for other software that you have running!

View file

@ -1,4 +1,21 @@
# Updating your instance # Updating your instance
You should **always check the release notes/changelog** in case there are config deprecations, special update special update steps, etc.
Besides that, doing the following is generally enough:
## For OTP installations
```sh
# Download the new release
su pleroma -s $SHELL -lc "./bin/pleroma_ctl update"
# Migrate the database, you are advised to stop the instance before doing that
su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
```
## For from source installations (using git)
1. Go to the working directory of Pleroma (default is `/opt/pleroma`) 1. Go to the working directory of Pleroma (default is `/opt/pleroma`)
2. Run `git pull`. This pulls the latest changes from upstream. 2. Run `git pull`. This pulls the latest changes from upstream.
3. Run `mix deps.get`. This pulls in any new dependencies. 3. Run `mix deps.get`. This pulls in any new dependencies.

View file

@ -37,6 +37,11 @@ Feel free to contact us to be added to this list!
- Platforms: Android - Platforms: Android
- Features: Streaming Ready, Moderation, Text Formatting - Features: Streaming Ready, Moderation, Text Formatting
### Kyclos
- Source Code: <https://git.pleroma.social/pleroma/harbour-kyclos>
- Platforms: SailfishOS
- Features: No Streaming
### Nekonium ### Nekonium
- Homepage: [F-Droid Repository](https://repo.gdgd.jp.net/), [Google Play](https://play.google.com/store/apps/details?id=com.apps.nekonium), [Amazon](https://www.amazon.co.jp/dp/B076FXPRBC/) - Homepage: [F-Droid Repository](https://repo.gdgd.jp.net/), [Google Play](https://play.google.com/store/apps/details?id=com.apps.nekonium), [Amazon](https://www.amazon.co.jp/dp/B076FXPRBC/)
- Source: <https://gogs.gdgd.jp.net/lin/nekonium> - Source: <https://gogs.gdgd.jp.net/lin/nekonium>

View file

@ -143,10 +143,11 @@ config :pleroma, :mrf_user_allowlist,
* `:reject` rejects the message entirely * `:reject` rejects the message entirely
### :activitypub ### :activitypub
* ``unfollow_blocked``: Whether blocks result in people getting unfollowed * `unfollow_blocked`: Whether blocks result in people getting unfollowed
* ``outgoing_blocks``: Whether to federate blocks to other instances * `outgoing_blocks`: Whether to federate blocks to other instances
* ``deny_follow_blocked``: Whether to disallow following an account that has blocked the user in question * `deny_follow_blocked`: Whether to disallow following an account that has blocked the user in question
* ``sign_object_fetches``: Sign object fetches with HTTP signatures * `sign_object_fetches`: Sign object fetches with HTTP signatures
* `authorized_fetch_mode`: Require HTTP signatures for AP fetches
### :fetch_initial_posts ### :fetch_initial_posts
* `enabled`: if enabled, when a new user is federated with, fetch some of their latest posts * `enabled`: if enabled, when a new user is federated with, fetch some of their latest posts
@ -501,6 +502,10 @@ Email notifications settings.
- `:logo` - a path to a custom logo. Set it to `nil` to use the default Pleroma logo. - `:logo` - a path to a custom logo. Set it to `nil` to use the default Pleroma logo.
- `:styling` - a map with color settings for email templates. - `:styling` - a map with color settings for email templates.
### Pleroma.Emails.NewUsersDigestEmail
- `:enabled` - a boolean, enables new users admin digest email when `true`. Defaults to `false`.
## Background jobs ## Background jobs
### Oban ### Oban
@ -513,6 +518,7 @@ Configuration options described in [Oban readme](https://github.com/sorentwo/oba
* `verbose` - logs verbosity * `verbose` - logs verbosity
* `prune` - non-retryable jobs [pruning settings](https://github.com/sorentwo/oban#pruning) (`:disabled` / `{:maxlen, value}` / `{:maxage, value}`) * `prune` - non-retryable jobs [pruning settings](https://github.com/sorentwo/oban#pruning) (`:disabled` / `{:maxlen, value}` / `{:maxage, value}`)
* `queues` - job queues (see below) * `queues` - job queues (see below)
* `crontab` - periodic jobs, see [`Oban.Cron`](#obancron)
Pleroma has the following queues: Pleroma has the following queues:
@ -524,6 +530,12 @@ Pleroma has the following queues:
* `web_push` - Web push notifications * `web_push` - Web push notifications
* `scheduled_activities` - Scheduled activities, see [`Pleroma.ScheduledActivity`](#pleromascheduledactivity) * `scheduled_activities` - Scheduled activities, see [`Pleroma.ScheduledActivity`](#pleromascheduledactivity)
#### Oban.Cron
Pleroma has these periodic job workers:
`Pleroma.Workers.Cron.ClearOauthTokenWorker` - a job worker to cleanup expired oauth tokens.
Example: Example:
```elixir ```elixir
@ -534,6 +546,9 @@ config :pleroma, Oban,
queues: [ queues: [
federator_incoming: 50, federator_incoming: 50,
federator_outgoing: 50 federator_outgoing: 50
],
crontab: [
{"0 0 * * *", Pleroma.Workers.Cron.ClearOauthTokenWorker}
] ]
``` ```
@ -816,8 +831,7 @@ Configure OAuth 2 provider capabilities:
* `token_expires_in` - The lifetime in seconds of the access token. * `token_expires_in` - The lifetime in seconds of the access token.
* `issue_new_refresh_token` - Keeps old refresh token or generate new refresh token when to obtain an access token. * `issue_new_refresh_token` - Keeps old refresh token or generate new refresh token when to obtain an access token.
* `clean_expired_tokens` - Enable a background job to clean expired oauth tokens. Defaults to `false`. * `clean_expired_tokens` - Enable a background job to clean expired oauth tokens. Defaults to `false`. Interval settings sets in configuration periodic jobs [`Oban.Cron`](#obancron)
* `clean_expired_tokens_interval` - Interval to run the job to clean expired tokens. Defaults to `86_400_000` (24 hours).
## Link parsing ## Link parsing

View file

@ -1,4 +1,5 @@
# Message Rewrite Facility # Message Rewrite Facility
The Message Rewrite Facility (MRF) is a subsystem that is implemented as a series of hooks that allows the administrator to rewrite or discard messages. The Message Rewrite Facility (MRF) is a subsystem that is implemented as a series of hooks that allows the administrator to rewrite or discard messages.
Possible uses include: Possible uses include:
@ -10,7 +11,8 @@ Possible uses include:
* removing media from messages * removing media from messages
* sending only public messages to a specific instance * sending only public messages to a specific instance
The MRF provides user-configurable policies. The default policy is `NoOpPolicy`, which disables the MRF functionality. Pleroma also includes an easy to use policy called `SimplePolicy` which maps messages matching certain pre-defined criterion to actions built into the policy module. The MRF provides user-configurable policies. The default policy is `NoOpPolicy`, which disables the MRF functionality. Pleroma also includes an easy to use policy called `SimplePolicy` which maps messages matching certain pre-defined criterion to actions built into the policy module.
It is possible to use multiple, active MRF policies at the same time. It is possible to use multiple, active MRF policies at the same time.
## Quarantine Instances ## Quarantine Instances
@ -18,7 +20,8 @@ It is possible to use multiple, active MRF policies at the same time.
You have the ability to prevent from private / followers-only messages from federating with specific instances. Which means they will only get the public or unlisted messages from your instance. You have the ability to prevent from private / followers-only messages from federating with specific instances. Which means they will only get the public or unlisted messages from your instance.
If, for example, you're using `MIX_ENV=prod` aka using production mode, you would open your configuration file located in `config/prod.secret.exs` and edit or add the option under your `:instance` config object. Then you would specify the instance within quotes. If, for example, you're using `MIX_ENV=prod` aka using production mode, you would open your configuration file located in `config/prod.secret.exs` and edit or add the option under your `:instance` config object. Then you would specify the instance within quotes.
```
```elixir
config :pleroma, :instance, config :pleroma, :instance,
[...] [...]
quarantined_instances: ["instance.example", "other.example"] quarantined_instances: ["instance.example", "other.example"]
@ -28,15 +31,15 @@ config :pleroma, :instance,
`SimplePolicy` is capable of handling most common admin tasks. `SimplePolicy` is capable of handling most common admin tasks.
To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this: To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this:
``` ```elixir
config :pleroma, :instance, config :pleroma, :instance,
[...] [...]
rewrite_policy: Pleroma.Web.ActivityPub.MRF.SimplePolicy rewrite_policy: Pleroma.Web.ActivityPub.MRF.SimplePolicy
``` ```
Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are: Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are:
* `media_removal`: Servers in this group will have media stripped from incoming messages. * `media_removal`: Servers in this group will have media stripped from incoming messages.
* `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media. * `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media.
@ -50,7 +53,7 @@ Servers should be configured as lists.
This example will enable `SimplePolicy`, block media from `illegalporn.biz`, mark media as NSFW from `porn.biz` and `porn.business`, reject messages from `spam.com`, remove messages from `spam.university` from the federated timeline and block reports (flags) from `whiny.whiner`: This example will enable `SimplePolicy`, block media from `illegalporn.biz`, mark media as NSFW from `porn.biz` and `porn.business`, reject messages from `spam.com`, remove messages from `spam.university` from the federated timeline and block reports (flags) from `whiny.whiner`:
``` ```elixir
config :pleroma, :instance, config :pleroma, :instance,
rewrite_policy: [Pleroma.Web.ActivityPub.MRF.SimplePolicy] rewrite_policy: [Pleroma.Web.ActivityPub.MRF.SimplePolicy]
@ -60,30 +63,31 @@ config :pleroma, :mrf_simple,
reject: ["spam.com"], reject: ["spam.com"],
federated_timeline_removal: ["spam.university"], federated_timeline_removal: ["spam.university"],
report_removal: ["whiny.whiner"] report_removal: ["whiny.whiner"]
``` ```
### Use with Care ### Use with Care
The effects of MRF policies can be very drastic. It is important to use this functionality carefully. Always try to talk to an admin before writing an MRF policy concerning their instance. The effects of MRF policies can be very drastic. It is important to use this functionality carefully. Always try to talk to an admin before writing an MRF policy concerning their instance.
## Writing your own MRF Policy ## Writing your own MRF Policy
As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `rewrite_policy` config setting. As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `rewrite_policy` config setting.
For example, here is a sample policy module which rewrites all messages to "new message content": For example, here is a sample policy module which rewrites all messages to "new message content":
```elixir ```elixir
# This is a sample MRF policy which rewrites all Notes to have "new message defmodule Pleroma.Web.ActivityPub.MRF.RewritePolicy do
# content." @moduledoc "MRF policy which rewrites all Notes to have 'new message content'."
defmodule Site.RewritePolicy do @behaviour Pleroma.Web.ActivityPub.MRF
@behavior Pleroma.Web.ActivityPub.MRF
# Catch messages which contain Note objects with actual data to filter. # Catch messages which contain Note objects with actual data to filter.
# Capture the object as `object`, the message content as `content` and the # Capture the object as `object`, the message content as `content` and the
# message itself as `message`. # message itself as `message`.
@impl true @impl true
def filter(%{"type" => Create", "object" => {"type" => "Note", "content" => content} = object} = message) def filter(
%{"type" => "Create", "object" => %{"type" => "Note", "content" => content} = object} =
message
)
when is_binary(content) do when is_binary(content) do
# Subject / CW is stored as summary instead of `name` like other AS2 objects # Subject / CW is stored as summary instead of `name` like other AS2 objects
# because of Mastodon doing it that way. # because of Mastodon doing it that way.
@ -106,17 +110,22 @@ defmodule Site.RewritePolicy do
# Let all other messages through without modifying them. # Let all other messages through without modifying them.
@impl true @impl true
def filter(message), do: {:ok, message} def filter(message), do: {:ok, message}
@impl true
def describe do
{:ok, %{mrf_sample: %{content: "new message content"}}}`
end
end end
``` ```
If you save this file as `lib/site/mrf/rewrite_policy.ex`, it will be included when you next rebuild Pleroma. You can enable it in the configuration like so: If you save this file as `lib/pleroma/web/activity_pub/mrf/rewrite_policy.ex`, it will be included when you next rebuild Pleroma. You can enable it in the configuration like so:
``` ```elixir
config :pleroma, :instance, config :pleroma, :instance,
rewrite_policy: [ rewrite_policy: [
Pleroma.Web.ActivityPub.MRF.SimplePolicy, Pleroma.Web.ActivityPub.MRF.SimplePolicy,
Site.RewritePolicy Pleroma.Web.ActivityPub.MRF.RewritePolicy
] ]
``` ```
Please note that the Pleroma developers consider custom MRF policy modules to fall under the purview of the AGPL. As such, you are obligated to release the sources to your custom MRF policy modules upon request. Please note that the Pleroma developers consider custom MRF policy modules to fall under the purview of the AGPL. As such, you are obligated to release the sources to your custom MRF policy modules upon request.

View file

@ -259,19 +259,14 @@ su pleroma -s $SHELL -lc "./bin/pleroma_ctl user new joeuser joeuser@sld.tld --a
``` ```
This will create an account withe the username of 'joeuser' with the email address of joeuser@sld.tld, and set that user's account as an admin. This will result in a link that you can paste into the browser, which logs you in and enables you to set the password. This will create an account withe the username of 'joeuser' with the email address of joeuser@sld.tld, and set that user's account as an admin. This will result in a link that you can paste into the browser, which logs you in and enables you to set the password.
### Updating
Generally, doing the following is enough:
```sh
# Download the new release
su pleroma -s $SHELL -lc "./bin/pleroma_ctl update"
# Migrate the database, you are advised to stop the instance before doing that
su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
```
But you should **always check the release notes/changelog** in case there are config deprecations, special update steps, etc.
## Further reading ## Further reading
* [Backup your instance](../administration/backup.md) * [Backup your instance](../administration/backup.md)
* [Hardening your instance](../configuration/hardening.md) * [Hardening your instance](../configuration/hardening.md)
* [How to activate mediaproxy](../configuration/howto_mediaproxy.md) * [How to activate mediaproxy](../configuration/howto_mediaproxy.md)
* [Updating your instance](../administration/updating.md)
## Questions
Questions about the installation or didnt it work as it should be, ask in [#pleroma:matrix.org](https://matrix.heldscal.la/#/room/#freenode_#pleroma:matrix.org) or IRC Channel **#pleroma** on **Freenode**.

View file

@ -62,6 +62,6 @@ def validate_scheduled_at(changeset) do
def expires_late_enough?(scheduled_at) do def expires_late_enough?(scheduled_at) do
now = NaiveDateTime.utc_now() now = NaiveDateTime.utc_now()
diff = NaiveDateTime.diff(scheduled_at, now, :millisecond) diff = NaiveDateTime.diff(scheduled_at, now, :millisecond)
diff >= @min_activity_lifetime diff > @min_activity_lifetime
end end
end end

View file

@ -42,12 +42,9 @@ def start(_type, _args) do
children = children =
[ [
Pleroma.Repo, Pleroma.Repo,
Pleroma.Scheduler,
Pleroma.Config.TransferTask, Pleroma.Config.TransferTask,
Pleroma.Emoji, Pleroma.Emoji,
Pleroma.Captcha, Pleroma.Captcha,
Pleroma.Daemons.ScheduledActivityDaemon,
Pleroma.Daemons.ActivityExpirationDaemon,
Pleroma.Plugs.RateLimiter.Supervisor Pleroma.Plugs.RateLimiter.Supervisor
] ++ ] ++
cachex_children() ++ cachex_children() ++
@ -58,7 +55,6 @@ def start(_type, _args) do
{Oban, Pleroma.Config.get(Oban)} {Oban, Pleroma.Config.get(Oban)}
] ++ ] ++
task_children(@env) ++ task_children(@env) ++
oauth_cleanup_child(oauth_cleanup_enabled?()) ++
streamer_child(@env) ++ streamer_child(@env) ++
chat_child(@env, chat_enabled?()) ++ chat_child(@env, chat_enabled?()) ++
[ [
@ -160,20 +156,12 @@ defp build_cachex(type, opts),
defp chat_enabled?, do: Pleroma.Config.get([:chat, :enabled]) defp chat_enabled?, do: Pleroma.Config.get([:chat, :enabled])
defp oauth_cleanup_enabled?,
do: Pleroma.Config.get([:oauth2, :clean_expired_tokens], false)
defp streamer_child(:test), do: [] defp streamer_child(:test), do: []
defp streamer_child(_) do defp streamer_child(_) do
[Pleroma.Web.Streamer.supervisor()] [Pleroma.Web.Streamer.supervisor()]
end end
defp oauth_cleanup_child(true),
do: [Pleroma.Web.OAuth.Token.CleanWorker]
defp oauth_cleanup_child(_), do: []
defp chat_child(_env, true) do defp chat_child(_env, true) do
[Pleroma.Web.ChatChannel.ChatChannelState] [Pleroma.Web.ChatChannel.ChatChannelState]
end end

View file

@ -146,9 +146,7 @@ defp group_and_subkey_need_reboot?(group, key, value) do
defp update_env(group, key, nil), do: Application.delete_env(group, key) defp update_env(group, key, nil), do: Application.delete_env(group, key)
defp update_env(group, key, value), do: Application.put_env(group, key, value) defp update_env(group, key, value), do: Application.put_env(group, key, value)
defp restart(_, :pleroma, :test), do: Logger.warn("pleroma restarted") defp restart(_, :pleroma, env), do: Restarter.Pleroma.restart_after_boot(env)
defp restart(_, :pleroma, _), do: send(Restarter.Pleroma, :after_boot)
defp restart(started_applications, app, _) do defp restart(started_applications, app, _) do
with {^app, _, _} <- List.keyfind(started_applications, app, 0), with {^app, _, _} <- List.keyfind(started_applications, app, 0),

View file

@ -1,66 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Daemons.ActivityExpirationDaemon do
alias Pleroma.Activity
alias Pleroma.ActivityExpiration
alias Pleroma.Config
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web.CommonAPI
require Logger
use GenServer
import Ecto.Query
@schedule_interval :timer.minutes(1)
def start_link(_) do
GenServer.start_link(__MODULE__, nil)
end
@impl true
def init(_) do
if Config.get([ActivityExpiration, :enabled]) do
schedule_next()
{:ok, nil}
else
:ignore
end
end
def perform(:execute, expiration_id) do
try do
expiration =
ActivityExpiration
|> where([e], e.id == ^expiration_id)
|> Repo.one!()
activity = Activity.get_by_id_with_object(expiration.activity_id)
user = User.get_by_ap_id(activity.object.data["actor"])
CommonAPI.delete(activity.id, user)
rescue
error ->
Logger.error("#{__MODULE__} Couldn't delete expired activity: #{inspect(error)}")
end
end
@impl true
def handle_info(:perform, state) do
ActivityExpiration.due_expirations(@schedule_interval)
|> Enum.each(fn expiration ->
Pleroma.Workers.ActivityExpirationWorker.enqueue(
"activity_expiration",
%{"activity_expiration_id" => expiration.id}
)
end)
schedule_next()
{:noreply, state}
end
defp schedule_next do
Process.send_after(self(), :perform, @schedule_interval)
end
end

View file

@ -1,42 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Daemons.DigestEmailDaemon do
alias Pleroma.Repo
alias Pleroma.Workers.DigestEmailsWorker
import Ecto.Query
def perform do
config = Pleroma.Config.get([:email_notifications, :digest])
negative_interval = -Map.fetch!(config, :interval)
inactivity_threshold = Map.fetch!(config, :inactivity_threshold)
inactive_users_query = Pleroma.User.list_inactive_users_query(inactivity_threshold)
now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
from(u in inactive_users_query,
where: fragment(~s(? ->'digest' @> 'true'), u.email_notifications),
where: u.last_digest_emailed_at < datetime_add(^now, ^negative_interval, "day"),
select: u
)
|> Repo.all()
|> Enum.each(fn user ->
DigestEmailsWorker.enqueue("digest_email", %{"user_id" => user.id})
end)
end
@doc """
Send digest email to the given user.
Updates `last_digest_emailed_at` field for the user and returns the updated user.
"""
@spec perform(Pleroma.User.t()) :: Pleroma.User.t()
def perform(user) do
with %Swoosh.Email{} = email <- Pleroma.Emails.UserEmail.digest_email(user) do
Pleroma.Emails.Mailer.deliver_async(email)
end
Pleroma.User.touch_last_digest_emailed_at(user)
end
end

View file

@ -1,62 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Daemons.ScheduledActivityDaemon do
@moduledoc """
Sends scheduled activities to the job queue.
"""
alias Pleroma.Config
alias Pleroma.ScheduledActivity
alias Pleroma.User
alias Pleroma.Web.CommonAPI
use GenServer
require Logger
@schedule_interval :timer.minutes(1)
def start_link(_) do
GenServer.start_link(__MODULE__, nil)
end
def init(_) do
if Config.get([ScheduledActivity, :enabled]) do
schedule_next()
{:ok, nil}
else
:ignore
end
end
def perform(:execute, scheduled_activity_id) do
try do
{:ok, scheduled_activity} = ScheduledActivity.delete(scheduled_activity_id)
%User{} = user = User.get_cached_by_id(scheduled_activity.user_id)
{:ok, _result} = CommonAPI.post(user, scheduled_activity.params)
rescue
error ->
Logger.error(
"#{__MODULE__} Couldn't create a status from the scheduled activity: #{inspect(error)}"
)
end
end
def handle_info(:perform, state) do
ScheduledActivity.due_activities(@schedule_interval)
|> Enum.each(fn scheduled_activity ->
Pleroma.Workers.ScheduledActivityWorker.enqueue(
"execute",
%{"activity_id" => scheduled_activity.id}
)
end)
schedule_next()
{:noreply, state}
end
defp schedule_next do
Process.send_after(self(), :perform, @schedule_interval)
end
end

View file

@ -13,7 +13,7 @@ def list_modules_in_dir(dir, start) do
|> Enum.filter(&String.ends_with?(&1, ".ex")) |> Enum.filter(&String.ends_with?(&1, ".ex"))
|> Enum.map(fn filename -> |> Enum.map(fn filename ->
module = filename |> String.trim_trailing(".ex") |> Macro.camelize() module = filename |> String.trim_trailing(".ex") |> Macro.camelize()
String.to_existing_atom(start <> module) String.to_atom(start <> module)
end) end)
end end
end end

View file

@ -0,0 +1,32 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Emails.NewUsersDigestEmail do
use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email_styled}
defp instance_notify_email do
Pleroma.Config.get([:instance, :notify_email]) || Pleroma.Config.get([:instance, :email])
end
def new_users(to, users_and_statuses) do
instance_name = Pleroma.Config.get([:instance, :name])
styling = Pleroma.Config.get([Pleroma.Emails.UserEmail, :styling])
logo_url =
Pleroma.Web.Endpoint.url() <>
Pleroma.Config.get([:frontend_configurations, :pleroma_fe, :logo])
new()
|> to({to.name, to.email})
|> from({instance_name, instance_notify_email()})
|> subject("#{instance_name} New Users")
|> render_body("new_users_digest.html", %{
title: "New Users",
users_and_statuses: users_and_statuses,
instance: instance_name,
styling: styling,
logo_url: logo_url
})
end
end

View file

@ -108,6 +108,7 @@ def extract_first_external_url(object, content) do
Cachex.fetch!(:scrubber_cache, key, fn _key -> Cachex.fetch!(:scrubber_cache, key, fn _key ->
result = result =
content content
|> Floki.parse_fragment!()
|> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"]") |> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"]")
|> Floki.attribute("a", "href") |> Floki.attribute("a", "href")
|> Enum.at(0) |> Enum.at(0)

View file

@ -4,6 +4,7 @@
defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
import Plug.Conn import Plug.Conn
import Phoenix.Controller, only: [get_format: 1, text: 2]
require Logger require Logger
def init(options) do def init(options) do
@ -15,25 +16,27 @@ def call(%{assigns: %{valid_signature: true}} = conn, _opts) do
end end
def call(conn, _opts) do def call(conn, _opts) do
headers = get_req_header(conn, "signature") if get_format(conn) == "activity+json" do
signature = Enum.at(headers, 0) conn
|> maybe_assign_valid_signature()
|> maybe_require_signature()
else
conn
end
end
if signature do defp maybe_assign_valid_signature(conn) do
if has_signature_header?(conn) do
# set (request-target) header to the appropriate value # set (request-target) header to the appropriate value
# we also replace the digest header with the one we computed # we also replace the digest header with the one we computed
conn = request_target = String.downcase("#{conn.method}") <> " #{conn.request_path}"
conn
|> put_req_header(
"(request-target)",
String.downcase("#{conn.method}") <> " #{conn.request_path}"
)
conn = conn =
if conn.assigns[:digest] do conn
conn |> put_req_header("(request-target)", request_target)
|> put_req_header("digest", conn.assigns[:digest]) |> case do
else %{assigns: %{digest: digest}} = conn -> put_req_header(conn, "digest", digest)
conn conn -> conn
end end
assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn)) assign(conn, :valid_signature, HTTPSignatures.validate_conn(conn))
@ -42,4 +45,21 @@ def call(conn, _opts) do
conn conn
end end
end end
defp has_signature_header?(conn) do
conn |> get_req_header("signature") |> Enum.at(0, false)
end
defp maybe_require_signature(%{assigns: %{valid_signature: true}} = conn), do: conn
defp maybe_require_signature(conn) do
if Pleroma.Config.get([:activitypub, :authorized_fetch_mode], false) do
conn
|> put_status(:unauthorized)
|> text("Request not signed")
|> halt()
else
conn
end
end
end end

View file

@ -5,15 +5,19 @@
defmodule Pleroma.ScheduledActivity do defmodule Pleroma.ScheduledActivity do
use Ecto.Schema use Ecto.Schema
alias Ecto.Multi
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.ScheduledActivity alias Pleroma.ScheduledActivity
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.CommonAPI.Utils alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Workers.ScheduledActivityWorker
import Ecto.Query import Ecto.Query
import Ecto.Changeset import Ecto.Changeset
@type t :: %__MODULE__{}
@min_offset :timer.minutes(5) @min_offset :timer.minutes(5)
schema "scheduled_activities" do schema "scheduled_activities" do
@ -105,16 +109,32 @@ def far_enough?(scheduled_at) do
end end
def new(%User{} = user, attrs) do def new(%User{} = user, attrs) do
%ScheduledActivity{user_id: user.id} changeset(%ScheduledActivity{user_id: user.id}, attrs)
|> changeset(attrs)
end end
@doc """
Creates ScheduledActivity and add to queue to perform at scheduled_at date
"""
@spec create(User.t(), map()) :: {:ok, ScheduledActivity.t()} | {:error, Ecto.Changeset.t()}
def create(%User{} = user, attrs) do def create(%User{} = user, attrs) do
user Multi.new()
|> new(attrs) |> Multi.insert(:scheduled_activity, new(user, attrs))
|> Repo.insert() |> maybe_add_jobs(Config.get([ScheduledActivity, :enabled]))
|> Repo.transaction()
|> transaction_response
end end
defp maybe_add_jobs(multi, true) do
multi
|> Multi.run(:scheduled_activity_job, fn _repo, %{scheduled_activity: activity} ->
%{activity_id: activity.id}
|> ScheduledActivityWorker.new(scheduled_at: activity.scheduled_at)
|> Oban.insert()
end)
end
defp maybe_add_jobs(multi, _), do: multi
def get(%User{} = user, scheduled_activity_id) do def get(%User{} = user, scheduled_activity_id) do
ScheduledActivity ScheduledActivity
|> where(user_id: ^user.id) |> where(user_id: ^user.id)
@ -122,25 +142,43 @@ def get(%User{} = user, scheduled_activity_id) do
|> Repo.one() |> Repo.one()
end end
def update(%ScheduledActivity{} = scheduled_activity, attrs) do @spec update(ScheduledActivity.t(), map()) ::
scheduled_activity {:ok, ScheduledActivity.t()} | {:error, Ecto.Changeset.t()}
|> update_changeset(attrs) def update(%ScheduledActivity{id: id} = scheduled_activity, attrs) do
|> Repo.update() with {:error, %Ecto.Changeset{valid?: true} = changeset} <-
{:error, update_changeset(scheduled_activity, attrs)} do
Multi.new()
|> Multi.update(:scheduled_activity, changeset)
|> Multi.update_all(:scheduled_job, job_query(id),
set: [scheduled_at: get_field(changeset, :scheduled_at)]
)
|> Repo.transaction()
|> transaction_response
end
end end
def delete(%ScheduledActivity{} = scheduled_activity) do @doc "Deletes a ScheduledActivity and linked jobs."
scheduled_activity @spec delete(ScheduledActivity.t() | binary() | integer) ::
|> Repo.delete() {:ok, ScheduledActivity.t()} | {:error, Ecto.Changeset.t()}
def delete(%ScheduledActivity{id: id} = scheduled_activity) do
Multi.new()
|> Multi.delete(:scheduled_activity, scheduled_activity, stale_error_field: :id)
|> Multi.delete_all(:jobs, job_query(id))
|> Repo.transaction()
|> transaction_response
end end
def delete(id) when is_binary(id) or is_integer(id) do def delete(id) when is_binary(id) or is_integer(id) do
ScheduledActivity delete(%__MODULE__{id: id})
|> where(id: ^id) end
|> select([sa], sa)
|> Repo.delete_all() defp transaction_response(result) do
|> case do case result do
{1, [scheduled_activity]} -> {:ok, scheduled_activity} {:ok, %{scheduled_activity: scheduled_activity}} ->
_ -> :error {:ok, scheduled_activity}
{:error, _, changeset, _} ->
{:error, changeset}
end end
end end
@ -158,4 +196,11 @@ def due_activities(offset \\ 0) do
|> where([sa], sa.scheduled_at < ^naive_datetime) |> where([sa], sa.scheduled_at < ^naive_datetime)
|> Repo.all() |> Repo.all()
end end
def job_query(scheduled_activity_id) do
from(j in Oban.Job,
where: j.queue == "scheduled_activities",
where: fragment("args ->> 'activity_id' = ?::text", ^to_string(scheduled_activity_id))
)
end
end end

View file

@ -1,7 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Scheduler do
use Quantum.Scheduler, otp_app: :pleroma
end

View file

@ -9,22 +9,43 @@ defmodule Pleroma.Stats do
use GenServer use GenServer
@interval 1000 * 60 * 60 @init_state %{
peers: [],
stats: %{
domain_count: 0,
status_count: 0,
user_count: 0
}
}
def start_link(_) do def start_link(_) do
GenServer.start_link(__MODULE__, initial_data(), name: __MODULE__) GenServer.start_link(
__MODULE__,
@init_state,
name: __MODULE__
)
end end
@doc "Performs update stats"
def force_update do def force_update do
GenServer.call(__MODULE__, :force_update) GenServer.call(__MODULE__, :force_update)
end end
@doc "Performs collect stats"
def do_collect do
GenServer.cast(__MODULE__, :run_update)
end
@doc "Returns stats data"
@spec get_stats() :: %{domain_count: integer(), status_count: integer(), user_count: integer()}
def get_stats do def get_stats do
%{stats: stats} = GenServer.call(__MODULE__, :get_state) %{stats: stats} = GenServer.call(__MODULE__, :get_state)
stats stats
end end
@doc "Returns list peers"
@spec get_peers() :: list(String.t())
def get_peers do def get_peers do
%{peers: peers} = GenServer.call(__MODULE__, :get_state) %{peers: peers} = GenServer.call(__MODULE__, :get_state)
@ -32,7 +53,6 @@ def get_peers do
end end
def init(args) do def init(args) do
Process.send(self(), :run_update, [])
{:ok, args} {:ok, args}
end end
@ -45,17 +65,12 @@ def handle_call(:get_state, _from, state) do
{:reply, state, state} {:reply, state, state}
end end
def handle_info(:run_update, _state) do def handle_cast(:run_update, _state) do
new_stats = get_stat_data() new_stats = get_stat_data()
Process.send_after(self(), :run_update, @interval)
{:noreply, new_stats} {:noreply, new_stats}
end end
defp initial_data do
%{peers: [], stats: %{}}
end
defp get_stat_data do defp get_stat_data do
peers = peers =
from( from(
@ -74,7 +89,11 @@ defp get_stat_data do
%{ %{
peers: peers, peers: peers,
stats: %{domain_count: domain_count, status_count: status_count, user_count: user_count} stats: %{
domain_count: domain_count,
status_count: status_count,
user_count: user_count
}
} }
end end
end end

View file

@ -17,6 +17,7 @@ defp old_user?(%User{} = u) do
# does the post contain links? # does the post contain links?
defp contains_links?(%{"content" => content} = _object) do defp contains_links?(%{"content" => content} = _object) do
content content
|> Floki.parse_fragment!()
|> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"],a.zrl") |> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"],a.zrl")
|> Floki.attribute("a", "href") |> Floki.attribute("a", "href")
|> length() > 0 |> length() > 0

View file

@ -5,12 +5,11 @@
defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do
alias Pleroma.Config alias Pleroma.Config
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF
require Pleroma.Constants require Pleroma.Constants
@moduledoc "Filter activities depending on their age" @moduledoc "Filter activities depending on their age"
@behaviour MRF @behaviour Pleroma.Web.ActivityPub.MRF
defp check_date(%{"published" => published} = message) do defp check_date(%{"published" => published} = message) do
with %DateTime{} = now <- DateTime.utc_now(), with %DateTime{} = now <- DateTime.utc_now(),

View file

@ -6,7 +6,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF alias Pleroma.Web.ActivityPub.MRF
@moduledoc "Filter activities depending on their origin instance" @moduledoc "Filter activities depending on their origin instance"
@behaviour MRF @behaviour Pleroma.Web.ActivityPub.MRF
require Pleroma.Constants require Pleroma.Constants

View file

@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicy do
require Logger require Logger
@behaviour MRF @behaviour Pleroma.Web.ActivityPub.MRF
defp lookup_subchain(actor) do defp lookup_subchain(actor) do
with matches <- Config.get([:mrf_subchain, :match_actor]), with matches <- Config.get([:mrf_subchain, :match_actor]),

View file

@ -8,6 +8,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
import Pleroma.Web.ControllerHelper, only: [json_response: 3] import Pleroma.Web.ControllerHelper, only: [json_response: 3]
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.ConfigDB alias Pleroma.ConfigDB
alias Pleroma.ModerationLog alias Pleroma.ModerationLog
alias Pleroma.Plugs.OAuthScopesPlug alias Pleroma.Plugs.OAuthScopesPlug
@ -570,8 +571,8 @@ def relay_unfollow(%{assigns: %{user: admin}} = conn, %{"relay_url" => target})
@doc "Sends registration invite via email" @doc "Sends registration invite via email"
def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do def email_invite(%{assigns: %{user: user}} = conn, %{"email" => email} = params) do
with true <- with true <-
Pleroma.Config.get([:instance, :invites_enabled]) && Config.get([:instance, :invites_enabled]) &&
!Pleroma.Config.get([:instance, :registrations_open]), !Config.get([:instance, :registrations_open]),
{:ok, invite_token} <- UserInviteToken.create_invite(), {:ok, invite_token} <- UserInviteToken.create_invite(),
email <- email <-
Pleroma.Emails.UserEmail.user_invitation_email( Pleroma.Emails.UserEmail.user_invitation_email(
@ -808,7 +809,7 @@ def config_show(conn, _params) do
configs = ConfigDB.get_all_as_keyword() configs = ConfigDB.get_all_as_keyword()
merged = merged =
Pleroma.Config.Holder.config() Config.Holder.config()
|> ConfigDB.merge(configs) |> ConfigDB.merge(configs)
|> Enum.map(fn {group, values} -> |> Enum.map(fn {group, values} ->
Enum.map(values, fn {key, value} -> Enum.map(values, fn {key, value} ->
@ -838,7 +839,16 @@ def config_show(conn, _params) do
end) end)
|> List.flatten() |> List.flatten()
json(conn, %{configs: merged}) response = %{configs: merged}
response =
if Restarter.Pleroma.need_reboot?() do
Map.put(response, :need_reboot, true)
else
response
end
json(conn, response)
end end
end end
@ -863,20 +873,26 @@ def config_update(conn, %{"configs" => configs}) do
Ecto.get_meta(config, :state) == :deleted Ecto.get_meta(config, :state) == :deleted
end) end)
Pleroma.Config.TransferTask.load_and_update_env(deleted, false) Config.TransferTask.load_and_update_env(deleted, false)
need_reboot? = need_reboot? =
Enum.any?(updated, fn config -> Restarter.Pleroma.need_reboot?() ||
group = ConfigDB.from_string(config.group) Enum.any?(updated, fn config ->
key = ConfigDB.from_string(config.key) group = ConfigDB.from_string(config.group)
value = ConfigDB.from_binary(config.value) key = ConfigDB.from_string(config.key)
Pleroma.Config.TransferTask.pleroma_need_restart?(group, key, value) value = ConfigDB.from_binary(config.value)
end) Config.TransferTask.pleroma_need_restart?(group, key, value)
end)
response = %{configs: updated} response = %{configs: updated}
response = response =
if need_reboot?, do: Map.put(response, :need_reboot, need_reboot?), else: response if need_reboot? do
Restarter.Pleroma.need_reboot()
Map.put(response, :need_reboot, need_reboot?)
else
response
end
conn conn
|> put_view(ConfigView) |> put_view(ConfigView)
@ -886,18 +902,14 @@ def config_update(conn, %{"configs" => configs}) do
def restart(conn, _params) do def restart(conn, _params) do
with :ok <- configurable_from_database(conn) do with :ok <- configurable_from_database(conn) do
if Pleroma.Config.get(:env) == :test do Restarter.Pleroma.restart(Config.get(:env), 50)
Logger.warn("pleroma restarted")
else
send(Restarter.Pleroma, {:restart, 50})
end
json(conn, %{}) json(conn, %{})
end end
end end
defp configurable_from_database(conn) do defp configurable_from_database(conn) do
if Pleroma.Config.get(:configurable_from_database) do if Config.get(:configurable_from_database) do
:ok :ok
else else
errors( errors(

View file

@ -228,9 +228,9 @@ def make_content_html(
data, data,
visibility visibility
) do ) do
no_attachment_links = attachment_links =
data data
|> Map.get("no_attachment_links", Config.get([:instance, :no_attachment_links])) |> Map.get("attachment_links", Config.get([:instance, :attachment_links]))
|> truthy_param?() |> truthy_param?()
content_type = get_content_type(data["content_type"]) content_type = get_content_type(data["content_type"])
@ -244,7 +244,7 @@ def make_content_html(
status status
|> format_input(content_type, options) |> format_input(content_type, options)
|> maybe_add_attachments(attachments, no_attachment_links) |> maybe_add_attachments(attachments, attachment_links)
|> maybe_add_nsfw_tag(data) |> maybe_add_nsfw_tag(data)
end end
@ -270,7 +270,7 @@ def make_context(_, %Participation{} = participation) do
def make_context(%Activity{data: %{"context" => context}}, _), do: context def make_context(%Activity{data: %{"context" => context}}, _), do: context
def make_context(_, _), do: Utils.generate_context_id() def make_context(_, _), do: Utils.generate_context_id()
def maybe_add_attachments(parsed, _attachments, true = _no_links), do: parsed def maybe_add_attachments(parsed, _attachments, false = _no_links), do: parsed
def maybe_add_attachments({text, mentions, tags}, attachments, _no_links) do def maybe_add_attachments({text, mentions, tags}, attachments, _no_links) do
text = add_attachments(text, attachments) text = add_attachments(text, attachments)

View file

@ -124,15 +124,18 @@ def create(
) do ) do
params = Map.put(params, "in_reply_to_status_id", params["in_reply_to_id"]) params = Map.put(params, "in_reply_to_status_id", params["in_reply_to_id"])
if ScheduledActivity.far_enough?(scheduled_at) do with {:far_enough, true} <- {:far_enough, ScheduledActivity.far_enough?(scheduled_at)},
with {:ok, scheduled_activity} <- attrs <- %{"params" => params, "scheduled_at" => scheduled_at},
ScheduledActivity.create(user, %{"params" => params, "scheduled_at" => scheduled_at}) do {:ok, scheduled_activity} <- ScheduledActivity.create(user, attrs) do
conn conn
|> put_view(ScheduledActivityView) |> put_view(ScheduledActivityView)
|> render("show.json", scheduled_activity: scheduled_activity) |> render("show.json", scheduled_activity: scheduled_activity)
end
else else
create(conn, Map.drop(params, ["scheduled_at"])) {:far_enough, _} ->
create(conn, Map.drop(params, ["scheduled_at"]))
error ->
error
end end
end end

View file

@ -175,9 +175,11 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
expires_at = expires_at =
with true <- client_posted_this_activity, with true <- client_posted_this_activity,
expiration when not is_nil(expiration) <- %ActivityExpiration{scheduled_at: scheduled_at} <-
ActivityExpiration.get_by_activity_id(activity.id) do ActivityExpiration.get_by_activity_id(activity.id) do
expiration.scheduled_at scheduled_at
else
_ -> nil
end end
thread_muted? = thread_muted? =
@ -242,9 +244,9 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
with %{data: %{"reactions" => emoji_reactions}} <- object do with %{data: %{"reactions" => emoji_reactions}} <- object do
Enum.map(emoji_reactions, fn [emoji, users] -> Enum.map(emoji_reactions, fn [emoji, users] ->
%{ %{
emoji: emoji, name: emoji,
count: length(users), count: length(users),
reacted: !!(opts[:for] && opts[:for].ap_id in users) me: !!(opts[:for] && opts[:for].ap_id in users)
} }
end) end)
else else
@ -321,11 +323,9 @@ def render("card.json", %{rich_media: rich_media, page_url: page_url}) do
nil nil
end end
site_name = rich_media[:site_name] || page_url_data.host
%{ %{
type: "link", type: "link",
provider_name: site_name, provider_name: page_url_data.host,
provider_url: page_url_data.scheme <> "://" <> page_url_data.host, provider_url: page_url_data.scheme <> "://" <> page_url_data.host,
url: page_url, url: page_url,
image: image_url |> MediaProxy.url(), image: image_url |> MediaProxy.url(),

View file

@ -8,8 +8,10 @@ defmodule Pleroma.Web.Metadata.Providers.RelMe do
@impl Provider @impl Provider
def build_tags(%{user: user}) do def build_tags(%{user: user}) do
(Floki.attribute(user.bio, "link[rel~=me]", "href") ++ bio_tree = Floki.parse_fragment!(user.bio)
Floki.attribute(user.bio, "a[rel~=me]", "href"))
(Floki.attribute(bio_tree, "link[rel~=me]", "href") ++
Floki.attribute(bio_tree, "a[rel~=me]", "href"))
|> Enum.map(fn link -> |> Enum.map(fn link ->
{:link, [rel: "me", href: link], []} {:link, [rel: "me", href: link], []}
end) end)

View file

@ -50,10 +50,10 @@ def raw_nodeinfo do
data data
|> Map.merge(%{quarantined_instances: quarantined}) |> Map.merge(%{quarantined_instances: quarantined})
|> Map.put(:enabled, Config.get([:instance, :federating]))
else else
%{} %{}
end end
|> Map.put(:enabled, Config.get([:instance, :federating]))
features = features =
[ [

View file

@ -1,34 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.OAuth.Token.CleanWorker do
@moduledoc """
The module represents functions to clean an expired oauth tokens.
"""
use GenServer
@ten_seconds 10_000
@one_day 86_400_000
alias Pleroma.Web.OAuth.Token
alias Pleroma.Workers.BackgroundWorker
def start_link(_), do: GenServer.start_link(__MODULE__, %{})
def init(_) do
Process.send_after(self(), :perform, @ten_seconds)
{:ok, nil}
end
@doc false
def handle_info(:perform, state) do
BackgroundWorker.enqueue("clean_expired_tokens", %{})
interval = Pleroma.Config.get([:oauth2, :clean_expired_tokens_interval], @one_day)
Process.send_after(self(), :perform, interval)
{:noreply, state}
end
def perform(:clean), do: Token.delete_expired_tokens()
end

View file

@ -53,10 +53,10 @@ def emoji_reactions_by(%{assigns: %{user: user}} = conn, %{"id" => activity_id})
|> Enum.filter(& &1) |> Enum.filter(& &1)
%{ %{
emoji: emoji, name: emoji,
count: length(users), count: length(users),
accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}), accounts: AccountView.render("index.json", %{users: users, for: user, as: :user}),
reacted: !!(user && user.ap_id in user_ap_ids) me: !!(user && user.ap_id in user_ap_ids)
} }
end) end)

View file

@ -27,9 +27,10 @@ def parse(_), do: {:error, "No URL provided"}
defp parse_url(url) do defp parse_url(url) do
with {:ok, %Tesla.Env{body: html, status: status}} when status in 200..299 <- with {:ok, %Tesla.Env{body: html, status: status}} when status in 200..299 <-
Pleroma.HTTP.get(url, [], adapter: @hackney_options), Pleroma.HTTP.get(url, [], adapter: @hackney_options),
{:ok, html_tree} <- Floki.parse_document(html),
data <- data <-
Floki.attribute(html, "link[rel~=me]", "href") ++ Floki.attribute(html_tree, "link[rel~=me]", "href") ++
Floki.attribute(html, "a[rel~=me]", "href") do Floki.attribute(html_tree, "a[rel~=me]", "href") do
{:ok, data} {:ok, data}
end end
rescue rescue

View file

@ -81,18 +81,18 @@ defp parse_url(url) do
{:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: @hackney_options) {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: @hackney_options)
html html
|> parse_html |> parse_html()
|> maybe_parse() |> maybe_parse()
|> Map.put(:url, url) |> Map.put(:url, url)
|> clean_parsed_data() |> clean_parsed_data()
|> check_parsed_data() |> check_parsed_data()
rescue rescue
e -> e ->
{:error, "Parsing error: #{inspect(e)}"} {:error, "Parsing error: #{inspect(e)} #{inspect(__STACKTRACE__)}"}
end end
end end
defp parse_html(html), do: Floki.parse(html) defp parse_html(html), do: Floki.parse_document!(html)
defp maybe_parse(html) do defp maybe_parse(html) do
Enum.reduce_while(parsers(), %{}, fn parser, acc -> Enum.reduce_while(parsers(), %{}, fn parser, acc ->

View file

@ -271,7 +271,7 @@ defmodule Pleroma.Web.Router do
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
pipe_through(:api) pipe_through(:api)
get("/statuses/:id/emoji_reactions_by", PleromaAPIController, :emoji_reactions_by) get("/statuses/:id/reactions", PleromaAPIController, :emoji_reactions_by)
end end
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
@ -287,8 +287,8 @@ defmodule Pleroma.Web.Router do
pipe_through(:authenticated_api) pipe_through(:authenticated_api)
patch("/conversations/:id", PleromaAPIController, :update_conversation) patch("/conversations/:id", PleromaAPIController, :update_conversation)
post("/statuses/:id/react_with_emoji", PleromaAPIController, :react_with_emoji) put("/statuses/:id/reactions/:emoji", PleromaAPIController, :react_with_emoji)
post("/statuses/:id/unreact_with_emoji", PleromaAPIController, :unreact_with_emoji) delete("/statuses/:id/reactions/:emoji", PleromaAPIController, :unreact_with_emoji)
post("/notifications/read", PleromaAPIController, :read_notification) post("/notifications/read", PleromaAPIController, :read_notification)
patch("/accounts/update_avatar", AccountController, :update_avatar) patch("/accounts/update_avatar", AccountController, :update_avatar)

View file

@ -0,0 +1,158 @@
<%= for {user, total_statuses, latest_status} <- @users_and_statuses do %>
<%# user card START %>
<div style="background-color:transparent;">
<div class="block-grid mixed-two-up no-stack"
style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
<div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="147" style="background-color:<%= @styling.content_background_color%>;width:76px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 20px; padding-top:5px; padding-bottom:5px;"><![endif]-->
<div class="col num3"
style="display: table-cell; vertical-align: top; max-width: 320px; min-width: 76px; width: 76px;">
<div style="width:100% !important;">
<!--[if (!mso)&(!IE)]><!-->
<div
style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 20px;">
<!--<![endif]-->
<div align="left" class="img-container left "
style="padding-right: 0px;padding-left: 0px;">
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr style="line-height:0px"><td style="padding-right: 0px;padding-left: 0px;" align="left"><![endif]--><img
alt="<%= user.name %>" border="0" class="left " src="<%= avatar_url(user) %>"
style="text-decoration: none; -ms-interpolation-mode: bicubic; border: 0; height: auto; width: 100%; max-width: 76px; display: block;"
title="<%= user.name %>" width="76" />
<!--[if mso]></td></tr></table><![endif]-->
</div>
<!--[if (!mso)&(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
<!--[if (mso)|(IE)]></td><td align="center" width="442" style="background-color:<%= @styling.content_background_color%>;width:442px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
<div class="col num9"
style="display: table-cell; vertical-align: top; min-width: 320px; max-width: 441px; width: 442px;">
<div style="width:100% !important;">
<!--[if (!mso)&(!IE)]><!-->
<div
style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
<!--<![endif]-->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
<div
style="color:<%= @styling.text_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div
style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_color %>;">
<p style="font-size: 14px; line-height: 19px; margin: 0;"><span
style="font-size: 16px; color: <%= @styling.text_color %>;"><%= user.name %></span></p>
<p style="font-size: 14px; line-height: 19px; margin: 0;"><span
style="font-size: 16px;"><%= link "@" <> user.nickname, style: "color: #{@styling.link_color};text-decoration: none;", to: admin_user_url(user) %></span></p>
<p style="font-size: 14px; line-height: 19px; margin: 0;"><span
style="font-size: 16px;">Total: <%= total_statuses %></span></p>
</div>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!--[if (!mso)&(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<%# user card END %>
<%= if latest_status do %>
<div style="background-color:transparent;">
<div class="block-grid"
style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
<div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 15px; padding-left: 15px; padding-top:5px; padding-bottom:5px;"><![endif]-->
<div class="col num12"
style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
<div style="width:100% !important;">
<!--[if (!mso)&(!IE)]><!-->
<div
style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 15px; padding-left: 15px;">
<!--<![endif]-->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
<div
style="color:<%= @styling.text_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div
style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_color %>;">
<span style="font-size: 16px; line-height: 19px;"><%= raw latest_status.object.data["content"] %></span></div>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 15px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
<div
style="color:<%= @styling.text_muted_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:15px;">
<div
style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_muted_color %>;">
<p style="font-size: 14px; line-height: 16px; margin: 0;"><%= format_date latest_status.object.data["published"] %></p>
</div>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!--[if (!mso)&(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<% end %>
<%# divider start %>
<div style="background-color:transparent;">
<div class="block-grid"
style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
<div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
<div class="col num12"
style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
<div style="width:100% !important;">
<!--[if (!mso)&(!IE)]><!-->
<div
style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
<!--<![endif]-->
<table border="0" cellpadding="0" cellspacing="0" class="divider" role="presentation"
style="table-layout: fixed; vertical-align: top; border-spacing: 0; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; min-width: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"
valign="top" width="100%">
<tbody>
<tr style="vertical-align: top;" valign="top">
<td class="divider_inner"
style="word-break: break-word; vertical-align: top; min-width: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px;"
valign="top">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="divider_content"
height="0" role="presentation"
style="table-layout: fixed; vertical-align: top; border-spacing: 0; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-top: 1px solid <%= @styling.text_color %>; height: 0px;"
valign="top" width="100%">
<tbody>
<tr style="vertical-align: top;" valign="top">
<td height="0"
style="word-break: break-word; vertical-align: top; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"
valign="top"><span></span></td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<!--[if (!mso)&(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<%# divider end %>
<%# user card END %>
<% end %>

View file

@ -0,0 +1,193 @@
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<meta content="width=device-width" name="viewport" />
<!--[if !mso]><!-->
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<!--<![endif]-->
<title><%= @email.subject %></title>
<!--[if !mso]><!-->
<!--<![endif]-->
<style type="text/css">
body {
margin: 0;
padding: 0;
}
a {
color: <%= @styling.link_color %>;
text-decoration: none;
}
table,
td,
tr {
vertical-align: top;
border-collapse: collapse;
}
* {
line-height: inherit;
}
a[x-apple-data-detectors=true] {
color: inherit !important;
text-decoration: none !important;
}
</style>
<style id="media-query" type="text/css">
@media (max-width: 610px) {
.block-grid,
.col {
min-width: 320px !important;
max-width: 100% !important;
display: block !important;
}
.block-grid {
width: 100% !important;
}
.col {
width: 100% !important;
}
.col>div {
margin: 0 auto;
}
.no-stack .col {
min-width: 0 !important;
display: table-cell !important;
}
.no-stack.two-up .col {
width: 50% !important;
}
.no-stack .col.num4 {
width: 33% !important;
}
.no-stack .col.num8 {
width: 66% !important;
}
.no-stack .col.num4 {
width: 33% !important;
}
.no-stack .col.num3 {
width: 25% !important;
}
.no-stack .col.num6 {
width: 50% !important;
}
.no-stack .col.num9 {
width: 75% !important;
}
}
</style>
</head>
<body class="clean-body" style="margin: 0; padding: 0; -webkit-text-size-adjust: 100%; background-color: <%= @styling.background_color %>;">
<!--[if IE]><div class="ie-browser"><![endif]-->
<table bgcolor="<%= @styling.background_color %>" cellpadding="0" cellspacing="0" class="nl-container" role="presentation"
style="table-layout: fixed; vertical-align: top; min-width: 320px; Margin: 0 auto; border-spacing: 0; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: <%= @styling.background_color %>; width: 100%;"
valign="top" width="100%">
<tbody>
<tr style="vertical-align: top;" valign="top">
<td style="word-break: break-word; vertical-align: top;" valign="top">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color:<%= @styling.background_color %>"><![endif]-->
<%# header %>
<div style="background-color:transparent;">
<div class="block-grid"
style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
<div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
<div class="col num12"
style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
<div style="width:100% !important;">
<!--[if (!mso)&(!IE)]><!-->
<div
style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
<!--<![endif]-->
<div align="center" class="img-container center"
style="padding-right: 0px;padding-left: 0px;">
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr style="line-height:0px"><td style="padding-right: 0px;padding-left: 0px;" align="center"><![endif]--><img
align="center" alt="Image" border="0" class="center" src="<%= @logo_url %>"
style="text-decoration: none; -ms-interpolation-mode: bicubic; border: 0; height: 80px; width: auto; max-height: 80px; display: block;"
title="Image" height="80" />
<!--[if mso]></td></tr></table><![endif]-->
</div>
<!--[if (!mso)&(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<%# title %>
<%= if @title do %>
<div style="background-color:transparent;">
<div class="block-grid"
style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
<div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
<!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
<!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
<div class="col num12"
style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
<div style="width:100% !important;">
<!--[if (!mso)&(!IE)]><!-->
<div
style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
<!--<![endif]-->
<!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
<div
style="line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
<div
style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height: 14px; color: <%= @styling.header_color %>;">
<p style="line-height: 36px; text-align: center; margin: 0;"><span
style="font-size: 30px; color: <%= @styling.header_color %>;"><%= @title %></span></p>
</div>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!--[if (!mso)&(!IE)]><!-->
</div>
<!--<![endif]-->
</div>
</div>
<!--[if (mso)|(IE)]></td></tr></table><![endif]-->
<!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
</div>
</div>
</div>
<% end %>
<%= render @view_module, @view_template, assigns %>
</td>
</tr>
</tbody>
</table>
<!--[if (IE)]></div><![endif]-->
</body>
</html>

View file

@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server # Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
@ -69,7 +69,7 @@ defp is_status?(acct) do
def do_follow(%{assigns: %{user: %User{} = user}} = conn, %{"user" => %{"id" => id}}) do def do_follow(%{assigns: %{user: %User{} = user}} = conn, %{"user" => %{"id" => id}}) do
with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)}, with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
{:ok, _, _, _} <- CommonAPI.follow(user, followee) do {:ok, _, _, _} <- CommonAPI.follow(user, followee) do
render(conn, "followed.html", %{error: false}) redirect(conn, to: "/users/#{followee.id}")
else else
error -> error ->
handle_follow_error(conn, error) handle_follow_error(conn, error)
@ -80,7 +80,7 @@ def do_follow(conn, %{"authorization" => %{"name" => _, "password" => _, "id" =>
with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)}, with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
{_, {:ok, user}, _} <- {:auth, Authenticator.get_user(conn), followee}, {_, {:ok, user}, _} <- {:auth, Authenticator.get_user(conn), followee},
{:ok, _, _, _} <- CommonAPI.follow(user, followee) do {:ok, _, _, _} <- CommonAPI.follow(user, followee) do
render(conn, "followed.html", %{error: false}) redirect(conn, to: "/users/#{followee.id}")
else else
error -> error ->
handle_follow_error(conn, error) handle_follow_error(conn, error)

View file

@ -12,4 +12,8 @@ def format_date(date) when is_binary(date) do
|> Timex.parse!("{ISO:Extended:Z}") |> Timex.parse!("{ISO:Extended:Z}")
|> Timex.format!("{Mshort} {D}, {YYYY} {h24}:{m}") |> Timex.format!("{Mshort} {D}, {YYYY} {h24}:{m}")
end end
def admin_user_url(%{id: id}) do
Pleroma.Web.Endpoint.url() <> "/pleroma/admin/#/users/" <> id
end
end end

View file

@ -1,18 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.ActivityExpirationWorker do
use Pleroma.Workers.WorkerHelper, queue: "activity_expiration"
@impl Oban.Worker
def perform(
%{
"op" => "activity_expiration",
"activity_expiration_id" => activity_expiration_id
},
_job
) do
Pleroma.Daemons.ActivityExpirationDaemon.perform(:execute, activity_expiration_id)
end
end

View file

@ -6,7 +6,6 @@ defmodule Pleroma.Workers.BackgroundWorker do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
alias Pleroma.Web.OAuth.Token.CleanWorker
use Pleroma.Workers.WorkerHelper, queue: "background" use Pleroma.Workers.WorkerHelper, queue: "background"
@ -55,10 +54,6 @@ def perform(
User.perform(:follow_import, follower, followed_identifiers) User.perform(:follow_import, follower, followed_identifiers)
end end
def perform(%{"op" => "clean_expired_tokens"}, _job) do
CleanWorker.perform(:clean)
end
def perform(%{"op" => "media_proxy_preload", "message" => message}, _job) do def perform(%{"op" => "media_proxy_preload", "message" => message}, _job) do
MediaProxyWarmingPolicy.perform(:preload, message) MediaProxyWarmingPolicy.perform(:preload, message)
end end

View file

@ -0,0 +1,21 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.Cron.ClearOauthTokenWorker do
@moduledoc """
The worker to cleanup expired oAuth tokens.
"""
use Oban.Worker, queue: "background"
alias Pleroma.Config
alias Pleroma.Web.OAuth.Token
@impl Oban.Worker
def perform(_opts, _job) do
if Config.get([:oauth2, :clean_expired_tokens], false) do
Token.delete_expired_tokens()
end
end
end

View file

@ -0,0 +1,58 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.Cron.DigestEmailsWorker do
@moduledoc """
The worker to send digest emails.
"""
use Oban.Worker, queue: "digest_emails"
alias Pleroma.Config
alias Pleroma.Emails
alias Pleroma.Repo
alias Pleroma.User
import Ecto.Query
require Logger
@impl Oban.Worker
def perform(_opts, _job) do
config = Config.get([:email_notifications, :digest])
if config[:active] do
negative_interval = -Map.fetch!(config, :interval)
inactivity_threshold = Map.fetch!(config, :inactivity_threshold)
inactive_users_query = User.list_inactive_users_query(inactivity_threshold)
now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
from(u in inactive_users_query,
where: fragment(~s(? ->'digest' @> 'true'), u.email_notifications),
where: u.last_digest_emailed_at < datetime_add(^now, ^negative_interval, "day"),
select: u
)
|> Repo.all()
|> send_emails
end
end
def send_emails(users) do
Enum.each(users, &send_email/1)
end
@doc """
Send digest email to the given user.
Updates `last_digest_emailed_at` field for the user and returns the updated user.
"""
@spec send_email(User.t()) :: User.t()
def send_email(user) do
with %Swoosh.Email{} = email <- Emails.UserEmail.digest_email(user) do
Emails.Mailer.deliver_async(email)
end
User.touch_last_digest_emailed_at(user)
end
end

View file

@ -0,0 +1,60 @@
# 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.NewUsersDigestWorker do
alias Pleroma.Activity
alias Pleroma.Repo
alias Pleroma.User
import Ecto.Query
use Pleroma.Workers.WorkerHelper, queue: "new_users_digest"
@impl Oban.Worker
def perform(_args, _job) do
if Pleroma.Config.get([Pleroma.Emails.NewUsersDigestEmail, :enabled]) do
today = NaiveDateTime.utc_now() |> Timex.beginning_of_day()
a_day_ago =
today
|> Timex.shift(days: -1)
|> Timex.beginning_of_day()
users_and_statuses =
%{
local: true,
order_by: :inserted_at
}
|> User.Query.build()
|> where([u], u.inserted_at >= ^a_day_ago and u.inserted_at < ^today)
|> Repo.all()
|> Enum.map(fn user ->
latest_status =
Activity
|> Activity.Queries.by_actor(user.ap_id)
|> Activity.Queries.by_type("Create")
|> Activity.with_preloaded_object()
|> order_by(desc: :inserted_at)
|> limit(1)
|> Repo.one()
total_statuses =
Activity
|> Activity.Queries.by_actor(user.ap_id)
|> Activity.Queries.by_type("Create")
|> Repo.aggregate(:count, :id)
{user, total_statuses, latest_status}
end)
if users_and_statuses != [] do
%{is_admin: true}
|> User.Query.build()
|> Repo.all()
|> Enum.map(&Pleroma.Emails.NewUsersDigestEmail.new_users(&1, users_and_statuses))
|> Enum.each(&Pleroma.Emails.Mailer.deliver/1)
end
end
end
end

View file

@ -0,0 +1,46 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker do
@moduledoc """
The worker to purge expired activities.
"""
use Oban.Worker, queue: "activity_expiration"
alias Pleroma.Activity
alias Pleroma.ActivityExpiration
alias Pleroma.Config
alias Pleroma.User
alias Pleroma.Web.CommonAPI
require Logger
@interval :timer.minutes(1)
@impl Oban.Worker
def perform(_opts, _job) do
if Config.get([ActivityExpiration, :enabled]) do
Enum.each(ActivityExpiration.due_expirations(@interval), &delete_activity/1)
end
end
def delete_activity(%ActivityExpiration{activity_id: activity_id}) do
with {:activity, %Activity{} = activity} <-
{:activity, Activity.get_by_id_with_object(activity_id)},
{:user, %User{} = user} <- {:user, User.get_by_ap_id(activity.object.data["actor"])} do
CommonAPI.delete(activity.id, user)
else
{:activity, _} ->
Logger.error(
"#{__MODULE__} Couldn't delete expired activity: not found activity ##{activity_id}"
)
{:user, _} ->
Logger.error(
"#{__MODULE__} Couldn't delete expired activity: not found actorof ##{activity_id}"
)
end
end
end

View file

@ -0,0 +1,16 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 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(_opts, _job) do
Pleroma.Stats.do_collect()
end
end

View file

@ -1,16 +0,0 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.DigestEmailsWorker do
alias Pleroma.User
use Pleroma.Workers.WorkerHelper, queue: "digest_emails"
@impl Oban.Worker
def perform(%{"op" => "digest_email", "user_id" => user_id}, _job) do
user_id
|> User.get_cached_by_id()
|> Pleroma.Daemons.DigestEmailDaemon.perform()
end
end

View file

@ -3,10 +3,42 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Workers.ScheduledActivityWorker do defmodule Pleroma.Workers.ScheduledActivityWorker do
@moduledoc """
The worker to post scheduled activity.
"""
use Pleroma.Workers.WorkerHelper, queue: "scheduled_activities" use Pleroma.Workers.WorkerHelper, queue: "scheduled_activities"
alias Pleroma.Config
alias Pleroma.ScheduledActivity
alias Pleroma.User
alias Pleroma.Web.CommonAPI
require Logger
@impl Oban.Worker @impl Oban.Worker
def perform(%{"op" => "execute", "activity_id" => activity_id}, _job) do def perform(%{"activity_id" => activity_id}, _job) do
Pleroma.Daemons.ScheduledActivityDaemon.perform(:execute, activity_id) if Config.get([ScheduledActivity, :enabled]) do
case Pleroma.Repo.get(ScheduledActivity, activity_id) do
%ScheduledActivity{} = scheduled_activity ->
post_activity(scheduled_activity)
_ ->
Logger.error("#{__MODULE__} Couldn't find scheduled activity: #{activity_id}")
end
end
end
defp post_activity(%ScheduledActivity{user_id: user_id, params: params} = scheduled_activity) do
with {:delete, {:ok, _}} <- {:delete, ScheduledActivity.delete(scheduled_activity)},
{:user, %User{} = user} <- {:user, User.get_cached_by_id(user_id)},
{:post, {:ok, _}} <- {:post, CommonAPI.post(user, params)} do
:ok
else
error ->
Logger.error(
"#{__MODULE__} Couldn't create a status from the scheduled activity: #{inspect(error)}"
)
end
end end
end end

13
mix.exs
View file

@ -63,7 +63,7 @@ def copy_nginx_config(%{path: target_path} = release) do
def application do def application do
[ [
mod: {Pleroma.Application, []}, mod: {Pleroma.Application, []},
extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize, :swarm], extra_applications: [:logger, :runtime_tools, :comeonin, :quack, :fast_sanitize],
included_applications: [:ex_syslogger] included_applications: [:ex_syslogger]
] ]
end end
@ -108,8 +108,7 @@ defp deps do
{:ecto_enum, "~> 1.4"}, {:ecto_enum, "~> 1.4"},
{:ecto_sql, "~> 3.3.2"}, {:ecto_sql, "~> 3.3.2"},
{:postgrex, ">= 0.13.5"}, {:postgrex, ">= 0.13.5"},
{:oban, "~> 0.12.0"}, {:oban, "~> 0.12.1"},
{:quantum, "~> 2.3"},
{:gettext, "~> 0.15"}, {:gettext, "~> 0.15"},
{:comeonin, "~> 4.1.1"}, {:comeonin, "~> 4.1.1"},
{:pbkdf2_elixir, "~> 0.12.3"}, {:pbkdf2_elixir, "~> 0.12.3"},
@ -140,8 +139,8 @@ defp deps do
{:phoenix_swoosh, "~> 0.2"}, {:phoenix_swoosh, "~> 0.2"},
{:gen_smtp, "~> 0.13"}, {:gen_smtp, "~> 0.13"},
{:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test}, {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test},
{:floki, "~> 0.23.0"}, {:ex_syslogger, "~> 1.4"},
{:ex_syslogger, github: "slashmili/ex_syslogger", tag: "1.4.0"}, {:floki, "~> 0.25"},
{:timex, "~> 3.5"}, {:timex, "~> 3.5"},
{:ueberauth, "~> 0.4"}, {:ueberauth, "~> 0.4"},
{:auto_linker, {:auto_linker,
@ -156,14 +155,14 @@ defp deps do
{:prometheus_plugs, "~> 1.1"}, {:prometheus_plugs, "~> 1.1"},
{:prometheus_phoenix, "~> 1.3"}, {:prometheus_phoenix, "~> 1.3"},
{:prometheus_ecto, "~> 1.4"}, {:prometheus_ecto, "~> 1.4"},
{:recon, github: "ferd/recon", tag: "2.4.0"}, {:recon, "~> 2.5"},
{:quack, "~> 0.1.1"}, {:quack, "~> 0.1.1"},
{:joken, "~> 2.0"}, {:joken, "~> 2.0"},
{:benchee, "~> 1.0"}, {:benchee, "~> 1.0"},
{:esshd, "~> 0.1.0", runtime: Application.get_env(:esshd, :enabled, false)}, {:esshd, "~> 0.1.0", runtime: Application.get_env(:esshd, :enabled, false)},
{:ex_const, "~> 0.2"}, {:ex_const, "~> 0.2"},
{:plug_static_index_html, "~> 1.0.0"}, {:plug_static_index_html, "~> 1.0.0"},
{:excoveralls, "~> 0.11.1", only: :test}, {:excoveralls, "~> 0.12.1", only: :test},
{:flake_id, "~> 0.1.0"}, {:flake_id, "~> 0.1.0"},
{:remote_ip, {:remote_ip,
git: "https://git.pleroma.social/pleroma/remote_ip.git", git: "https://git.pleroma.social/pleroma/remote_ip.git",

187
mix.lock
View file

@ -1,113 +1,110 @@
%{ %{
"accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm"}, "accept": {:hex, :accept, "0.3.5", "b33b127abca7cc948bbe6caa4c263369abf1347cfa9d8e699c6d214660f10cd1", [:rebar3], [], "hexpm", "11b18c220bcc2eab63b5470c038ef10eb6783bcb1fcdb11aa4137defa5ac1bb8"},
"auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]}, "auto_linker": {:git, "https://git.pleroma.social/pleroma/auto_linker.git", "95e8188490e97505c56636c1379ffdf036c1fdde", [ref: "95e8188490e97505c56636c1379ffdf036c1fdde"]},
"base62": {:hex, :base62, "1.2.1", "4866763e08555a7b3917064e9eef9194c41667276c51b59de2bc42c6ea65f806", [:mix], [{:custom_base, "~> 0.2.1", [hex: :custom_base, repo: "hexpm", optional: false]}], "hexpm"}, "base62": {:hex, :base62, "1.2.1", "4866763e08555a7b3917064e9eef9194c41667276c51b59de2bc42c6ea65f806", [:mix], [{:custom_base, "~> 0.2.1", [hex: :custom_base, repo: "hexpm", optional: false]}], "hexpm", "3b29948de2013d3f93aa898c884a9dff847e7aec75d9d6d8c1dc4c61c2716c42"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"}, "base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"bbcode": {:hex, :bbcode, "0.1.1", "0023e2c7814119b2e620b7add67182e3f6019f92bfec9a22da7e99821aceba70", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "bbcode": {:hex, :bbcode, "0.1.1", "0023e2c7814119b2e620b7add67182e3f6019f92bfec9a22da7e99821aceba70", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5a981b98ac7d366a9b6bf40eac389aaf4d6e623c631e6b6f8a6b571efaafd338"},
"benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm"}, "benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "3ad58ae787e9c7c94dd7ceda3b587ec2c64604563e049b2a0e8baafae832addb"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"cachex": {:hex, :cachex, "3.0.3", "4e2d3e05814a5738f5ff3903151d5c25636d72a3527251b753f501ad9c657967", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm"}, "cachex": {:hex, :cachex, "3.0.3", "4e2d3e05814a5738f5ff3903151d5c25636d72a3527251b753f501ad9c657967", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "3aadb1e605747122f60aa7b0b121cca23c14868558157563b3f3e19ea929f7d0"},
"calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, "calendar": {:hex, :calendar, "0.17.6", "ec291cb2e4ba499c2e8c0ef5f4ace974e2f9d02ae9e807e711a9b0c7850b9aee", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "738d0e17a93c2ccfe4ddc707bdc8e672e9074c8569498483feb1c4530fb91b2b"},
"captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]}, "captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]},
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "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"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
"comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"}, "comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm", "d8700a0ca4dbb616c22c9b3f6dd539d88deaafec3efe66869d6370c9a559b3e9"},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
"cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "9af027d20dc12dd0c4345a6b87247e0c62965871feea0bfecf9764648b02cc69"},
"cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, "cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "04fd8c6a39edc6aaa9c26123009200fc61f92a3a94f3178c527b70b767c6e605"},
"cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm"}, "cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"},
"credo": {:hex, :credo, "1.1.5", "caec7a3cadd2e58609d7ee25b3931b129e739e070539ad1a0cd7efeeb47014f4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "1.1.5", "caec7a3cadd2e58609d7ee25b3931b129e739e070539ad1a0cd7efeeb47014f4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d0bbd3222607ccaaac5c0340f7f525c627ae4d7aee6c8c8c108922620c5b6446"},
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]}, "crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm"}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.2.0", "e923e88887cd60f9891fd324ac5e0290954511d090553c415fbf54be4c57ee63", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, "db_connection": {:hex, :db_connection, "2.2.1", "caee17725495f5129cb7faebde001dc4406796f12a62b8949f4ac69315080566", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm"}, "decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"earmark": {:hex, :earmark, "1.4.2", "3aa0bd23bc4c61cf2f1e5d752d1bb470560a6f8539974f767a38923bb20e1d7f", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm"},
"ecto": {:hex, :ecto, "3.3.1", "82ab74298065bf0c64ca299f6c6785e68ea5d6b980883ee80b044499df35aba1", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, "ecto": {:hex, :ecto, "3.3.3", "0830bf3aebcbf3d8c1a1811cd581773b6866886c012f52c0f027031fa96a0b53", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm"}, "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
"ecto_sql": {:hex, :ecto_sql, "3.3.2", "92804e0de69bb63e621273c3492252cb08a29475c05d40eeb6f41ad2d483cfd3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "ecto_sql": {:hex, :ecto_sql, "3.3.4", "aa18af12eb875fbcda2f75e608b3bd534ebf020fc4f6448e4672fcdcbb081244", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4 or ~> 3.3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"esshd": {:hex, :esshd, "0.1.0", "6f93a2062adb43637edad0ea7357db2702a4b80dd9683482fe00f5134e97f4c1", [:mix], [], "hexpm"}, "esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm"},
"eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm"}, "eternal": {:hex, :eternal, "1.2.1", "d5b6b2499ba876c57be2581b5b999ee9bdf861c647401066d3eeed111d096bc4", [:mix], [], "hexpm", "b14f1dc204321429479c569cfbe8fb287541184ed040956c8862cb7a677b8406"},
"ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"}, "ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"},
"ex_aws": {:hex, :ex_aws, "2.1.1", "1e4de2106cfbf4e837de41be41cd15813eabc722315e388f0d6bb3732cec47cd", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"}, "ex_aws": {:hex, :ex_aws, "2.1.1", "1e4de2106cfbf4e837de41be41cd15813eabc722315e388f0d6bb3732cec47cd", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "06b6fde12b33bb6d65d5d3493e903ba5a56d57a72350c15285a4298338089e10"},
"ex_aws_s3": {:hex, :ex_aws_s3, "2.0.2", "c0258bbdfea55de4f98f0b2f0ca61fe402cc696f573815134beb1866e778f47b", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm"}, "ex_aws_s3": {:hex, :ex_aws_s3, "2.0.2", "c0258bbdfea55de4f98f0b2f0ca61fe402cc696f573815134beb1866e778f47b", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "0569f5b211b1a3b12b705fe2a9d0e237eb1360b9d76298028df2346cad13097a"},
"ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm"}, "ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"},
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [: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"}, "ex_machina": {:hex, :ex_machina, "2.3.0", "92a5ad0a8b10ea6314b876a99c8c9e3f25f4dde71a2a835845b136b9adaf199a", [: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", "b84f6af156264530b312a8ab98ac6088f6b77ae5fe2058305c81434aa01fbaf9"},
"ex_syslogger": {:git, "https://github.com/slashmili/ex_syslogger.git", "f3963399047af17e038897c69e20d552e6899e1d", [tag: "1.4.0"]}, "ex_syslogger": {:hex, :ex_syslogger, "1.5.0", "bc936ee3fd13d9e592cb4c3a1e8a55fccd33b05e3aa7b185f211f3ed263ff8f0", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.0.5", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm"},
"excoveralls": {:hex, :excoveralls, "0.11.2", "0c6f2c8db7683b0caa9d490fb8125709c54580b4255ffa7ad35f3264b075a643", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.12.2", "a513defac45c59e310ac42fcf2b8ae96f1f85746410f30b1ff2b710a4b6cd44b", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"fast_html": {:hex, :fast_html, "1.0.1", "5bc7df4dc4607ec2c314c16414e4111d79a209956c4f5df96602d194c61197f9", [:make, :mix], [], "hexpm"}, "fast_html": {:hex, :fast_html, "1.0.3", "2cc0d4b68496266a1530e0c852cafeaede0bd10cfdee26fda50dc696c203162f", [:make, :mix], [], "hexpm", "ab3d782b639d3c4655fbaec0f9d032c91f8cab8dd791ac7469c2381bc7c32f85"},
"fast_sanitize": {:hex, :fast_sanitize, "0.1.6", "60a5ae96879956dea409a91a77f5dd2994c24cc10f80eefd8f9892ee4c0c7b25", [:mix], [{:fast_html, "~> 1.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "fast_sanitize": {:hex, :fast_sanitize, "0.1.7", "2a7cd8734c88a2de6de55022104f8a3b87f1fdbe8bbf131d9049764b53d50d0d", [:mix], [{:fast_html, "~> 1.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f39fe8ea08fbac17487c30bf09b7d9f3e12472e51fb07a88ffeb8fd17da8ab67"},
"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"}, "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"},
"floki": {:hex, :floki, "0.23.1", "e100306ce7d8841d70a559748e5091542e2cfc67ffb3ade92b89a8435034dab1", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm"}, "floki": {:hex, :floki, "0.25.0", "b1c9ddf5f32a3a90b43b76f3386ca054325dc2478af020e87b5111c19f2284ac", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm"},
"gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm"}, "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"},
"gen_stage": {:hex, :gen_stage, "0.14.3", "d0c66f1c87faa301c1a85a809a3ee9097a4264b2edf7644bf5c123237ef732bf", [:mix], [], "hexpm"}, "gen_stage": {:hex, :gen_stage, "0.14.3", "d0c66f1c87faa301c1a85a809a3ee9097a4264b2edf7644bf5c123237ef732bf", [:mix], [], "hexpm"},
"gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"}, "gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"},
"gettext": {:hex, :gettext, "0.17.1", "8baab33482df4907b3eae22f719da492cee3981a26e649b9c2be1c0192616962", [:mix], [], "hexpm"}, "gettext": {:hex, :gettext, "0.17.4", "f13088e1ec10ce01665cf25f5ff779e7df3f2dc71b37084976cf89d1aa124d5c", [:mix], [], "hexpm"},
"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"}, "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.0", "40f5c5b9cbe23073b48a4e69c67b6c11974f623a76165e2b92d098c0e88ccb1d", [:mix], [], "hexpm"}, "html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm"},
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
"http_signatures": {:git, "https://git.pleroma.social/pleroma/http_signatures.git", "293d77bb6f4a67ac8bde1428735c3b42f22cbb30", [ref: "293d77bb6f4a67ac8bde1428735c3b42f22cbb30"]}, "http_signatures": {:git, "https://git.pleroma.social/pleroma/http_signatures.git", "293d77bb6f4a67ac8bde1428735c3b42f22cbb30", [ref: "293d77bb6f4a67ac8bde1428735c3b42f22cbb30"]},
"httpoison": {:hex, :httpoison, "1.6.1", "2ce5bf6e535cd0ab02e905ba8c276580bab80052c5c549f53ddea52d72e81f33", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "httpoison": {:hex, :httpoison, "1.6.2", "ace7c8d3a361cebccbed19c283c349b3d26991eff73a1eaaa8abae2e3c8089b6", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "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"}, "inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"},
"joken": {:hex, :joken, "2.1.0", "bf21a73105d82649f617c5e59a7f8919aa47013d2519ebcc39d998d8d12adda9", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm"}, "joken": {:hex, :joken, "2.2.0", "2daa1b12be05184aff7b5ace1d43ca1f81345962285fff3f88db74927c954d3a", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm"},
"jose": {:hex, :jose, "1.9.0", "4167c5f6d06ffaebffd15cdb8da61a108445ef5e85ab8f5a7ad926fdf3ada154", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"}, "jose": {:hex, :jose, "1.10.1", "16d8e460dae7203c6d1efa3f277e25b5af8b659febfc2f2eb4bacf87f128b80a", [:mix, :rebar3], [], "hexpm"},
"libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"}, "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"},
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm"}, "meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"}, "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"},
"mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"}, "mock": {:hex, :mock, "0.3.4", "c5862eb3b8c64237f45f586cf00c9d892ba07bb48305a43319d428ce3c2897dd", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "e6d886252f1a41f4ba06ecf2b4c8d38760b34b1c08a11c28f7397b2e03995964"},
"mogrify": {:hex, :mogrify, "0.6.1", "de1b527514f2d95a7bbe9642eb556061afb337e220cf97adbf3a4e6438ed70af", [:mix], [], "hexpm"}, "mogrify": {:hex, :mogrify, "0.6.1", "de1b527514f2d95a7bbe9642eb556061afb337e220cf97adbf3a4e6438ed70af", [:mix], [], "hexpm", "3bc928d817974fa10cc11e6c89b9a9361e37e96dbbf3d868c41094ec05745dcd"},
"mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm"}, "mox": {:hex, :mox, "0.5.1", "f86bb36026aac1e6f924a4b6d024b05e9adbed5c63e8daa069bd66fb3292165b", [:mix], [], "hexpm", "052346cf322311c49a0f22789f3698eea030eec09b8c47367f0686ef2634ae14"},
"mrfcontrib": {:git, "https://github.com/FloatingGhost/pleroma-mrf-contrib.git", "8cecf964b6f9686ab11687e8267bc238a19bd3b6", [tag: "v0.0.5"]},
"myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]}, "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm"},
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
"oban": {:hex, :oban, "0.12.1", "695e9490c6e0edfca616d80639528e448bd29b3bff7b7dd10a56c79b00a5d7fb", [:mix], [{:ecto_sql, "~> 3.1", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "oban": {:hex, :oban, "0.12.1", "695e9490c6e0edfca616d80639528e448bd29b3bff7b7dd10a56c79b00a5d7fb", [:mix], [{:ecto_sql, "~> 3.1", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c1d58d69b8b5a86e7167abbb8cc92764a66f25f12f6172052595067fc6a30a17"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.4", "8dd29ed783f2e12195d7e0a4640effc0a7c37e6537da491f1db01839eee6d053", [:mix], [], "hexpm"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.4", "8dd29ed783f2e12195d7e0a4640effc0a7c37e6537da491f1db01839eee6d053", [:mix], [], "hexpm", "595d09db74cb093b1903381c9de423276a931a2480a46a1a5dc7f932a2a6375b"},
"phoenix": {:hex, :phoenix, "1.4.10", "619e4a545505f562cd294df52294372d012823f4fd9d34a6657a8b242898c255", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix": {:hex, :phoenix, "1.4.13", "67271ad69b51f3719354604f4a3f968f83aa61c19199343656c9caee057ff3b8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.8.1 or ~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.0.0", "c43117a136e7399ea04ecaac73f8f23ee0ffe3e07acfcb8062fe5f4c9f0f6531", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_html": {:hex, :phoenix_html, "2.13.3", "850e292ff6e204257f5f9c4c54a8cb1f6fbc16ed53d360c2b780a3d0ba333867", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_html": {:hex, :phoenix_html, "2.14.0", "d8c6bc28acc8e65f8ea0080ee05aa13d912c8758699283b8d3427b655aabe284", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm", "1f13f9f0f3e769a667a6b6828d29dec37497a082d195cc52dbef401a9b69bf38"},
"phoenix_swoosh": {:hex, :phoenix_swoosh, "0.2.0", "a7e0b32077cd6d2323ae15198839b05d9caddfa20663fd85787479e81f89520e", [:mix], [{:phoenix, "~> 1.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.2", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 0.1", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.2.0", "a7e0b32077cd6d2323ae15198839b05d9caddfa20663fd85787479e81f89520e", [:mix], [{:phoenix, "~> 1.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.2", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 0.1", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "ebf1bfa7b3c1c850c04929afe02e2e0d7ab135e0706332c865de03e761676b1f"},
"plug": {:hex, :plug, "1.9.0", "8d7c4e26962283ff9f8f3347bd73838e2413fbc38b7bb5467d5924f68f3a5a4a", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"}, "plug": {:hex, :plug, "1.9.0", "8d7c4e26962283ff9f8f3347bd73838e2413fbc38b7bb5467d5924f68f3a5a4a", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "9902eda2c52ada2a096434682e99a2493f5d06a94d6ac6bcfff9805f952350f1"},
"plug_cowboy": {:hex, :plug_cowboy, "2.1.0", "b75768153c3a8a9e8039d4b25bb9b14efbc58e9c4a6e6a270abff1cd30cbe320", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "plug_cowboy": {:hex, :plug_cowboy, "2.1.2", "8b0addb5908c5238fac38e442e81b6fcd32788eaa03246b4d55d147c47c5805e", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm"},
"plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"}, "postgrex": {:hex, :postgrex, "0.15.3", "5806baa8a19a68c4d07c7a624ccdb9b57e89cbc573f1b98099e3741214746ae4", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "4737ce62a31747b4c63c12b20c62307e51bb4fcd730ca0c32c280991e0606c90"},
"prometheus": {:hex, :prometheus, "4.4.1", "1e96073b3ed7788053768fea779cbc896ddc3bdd9ba60687f2ad50b252ac87d6", [:mix, :rebar3], [], "hexpm"}, "prometheus": {:hex, :prometheus, "4.5.0", "8f4a2246fe0beb50af0f77c5e0a5bb78fe575c34a9655d7f8bc743aad1c6bf76", [:mix, :rebar3], [], "hexpm"},
"prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"}, "prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"},
"prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm"}, "prometheus_ex": {:hex, :prometheus_ex, "3.0.5", "fa58cfd983487fc5ead331e9a3e0aa622c67232b3ec71710ced122c4c453a02f", [:mix], [{:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}], "hexpm", "9fd13404a48437e044b288b41f76e64acd9735fb8b0e3809f494811dfa66d0fb"},
"prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm"}, "prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "c4d1404ac4e9d3d963da601db2a7d8ea31194f0017057fabf0cfb9bf5a6c8c75"},
"prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm"}, "prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"},
"quack": {:hex, :quack, "0.1.1", "cca7b4da1a233757fdb44b3334fce80c94785b3ad5a602053b7a002b5a8967bf", [:mix], [{:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}, {:tesla, "~> 1.2.0", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm"}, "quack": {:hex, :quack, "0.1.1", "cca7b4da1a233757fdb44b3334fce80c94785b3ad5a602053b7a002b5a8967bf", [:mix], [{:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: false]}, {:tesla, "~> 1.2.0", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "d736bfa7444112eb840027bb887832a0e403a4a3437f48028c3b29a2dbbd2543"},
"quantum": {:hex, :quantum, "2.3.4", "72a0e8855e2adc101459eac8454787cb74ab4169de6ca50f670e72142d4960e9", [:mix], [{:calendar, "~> 0.17", [hex: :calendar, repo: "hexpm", optional: true]}, {:crontab, "~> 1.1", [hex: :crontab, repo: "hexpm", optional: false]}, {:gen_stage, "~> 0.12", [hex: :gen_stage, repo: "hexpm", optional: false]}, {:swarm, "~> 3.3", [hex: :swarm, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: true]}], "hexpm"}, "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"}, "recon": {:hex, :recon, "2.5.0", "2f7fcbec2c35034bade2f9717f77059dc54eb4e929a3049ca7ba6775c0bd66cd", [:mix, :rebar3], [], "hexpm"},
"recon": {:git, "https://github.com/ferd/recon.git", "75d70c7c08926d2f24f1ee6de14ee50fe8a52763", [tag: "2.4.0"]},
"remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "825dc00aaba5a1b7c4202a532b696b595dd3bcb3", [ref: "825dc00aaba5a1b7c4202a532b696b595dd3bcb3"]}, "remote_ip": {:git, "https://git.pleroma.social/pleroma/remote_ip.git", "825dc00aaba5a1b7c4202a532b696b595dd3bcb3", [ref: "825dc00aaba5a1b7c4202a532b696b595dd3bcb3"]},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"},
"swarm": {:hex, :swarm, "3.4.0", "64f8b30055d74640d2186c66354b33b999438692a91be275bb89cdc7e401f448", [:mix], [{:gen_state_machine, "~> 2.0", [hex: :gen_state_machine, repo: "hexpm", optional: false]}, {:libring, "~> 1.0", [hex: :libring, repo: "hexpm", optional: false]}], "hexpm"}, "sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"},
"sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm"}, "swoosh": {:hex, :swoosh, "0.23.5", "bfd9404bbf5069b1be2ffd317923ce57e58b332e25dbca2a35dedd7820dfee5a", [: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: false]}, {: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", "e3928e1d2889a308aaf3e42755809ac21cffd77cb58eef01cbfdab4ce2fd1e21"},
"swoosh": {:hex, :swoosh, "0.23.5", "bfd9404bbf5069b1be2ffd317923ce57e58b332e25dbca2a35dedd7820dfee5a", [: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: false]}, {: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"}, "syslog": {:hex, :syslog, "1.0.6", "995970c9aa7feb380ac493302138e308d6e04fd57da95b439a6df5bb3bf75076", [:rebar3], [], "hexpm"},
"syslog": {:git, "https://github.com/Vagabond/erlang-syslog.git", "4a6c6f2c996483e86c1320e9553f91d337bcb6aa", [tag: "1.0.5"]}, "telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"},
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm"}, "tesla": {:hex, :tesla, "1.3.2", "deb92c5c9ce35e747a395ba413ca78593a4f75bf0e1545630ee2e3d34264021e", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
"tesla": {:hex, :tesla, "1.3.0", "f35d72f029e608f9cdc6f6d6fcc7c66cf6d6512a70cfef9206b21b8bd0203a30", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 0.4", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"}, "timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [: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", "f354efb2400dd7a80fd9eb6c8419068c4f632da4ac47f3d8822d6e33f08bc852"},
"timex": {:hex, :timex, "3.6.1", "efdf56d0e67a6b956cc57774353b0329c8ab7726766a11547e529357ffdc1d56", [: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"}, "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "0.5.22", "f2ba9105117ee0360eae2eca389783ef7db36d533899b2e84559404dbc77ebb8", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "cd66c8a1e6a9e121d1f538b01bef459334bb4029a1ffb4eeeb5e4eae0337e7b6"},
"tzdata": {:hex, :tzdata, "0.5.22", "f2ba9105117ee0360eae2eca389783ef7db36d533899b2e84559404dbc77ebb8", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "ueberauth": {:hex, :ueberauth, "0.6.2", "25a31111249d60bad8b65438b2306a4dc91f3208faa62f5a8c33e8713989b2e8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "db9fbfb5ac707bc4f85a297758406340bf0358b4af737a88113c1a9eee120ac7"},
"ueberauth": {:hex, :ueberauth, "0.6.2", "25a31111249d60bad8b65438b2306a4dc91f3208faa62f5a8c33e8713989b2e8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, "unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"},
"unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm"}, "web_push_encryption": {:hex, :web_push_encryption, "0.2.3", "a0ceab85a805a30852f143d22d71c434046fbdbafbc7292e7887cec500826a80", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "9315c8f37c108835cf3f8e9157d7a9b8f420a34f402d1b1620a31aed5b93ecdf"},
"web_push_encryption": {:hex, :web_push_encryption, "0.2.3", "a0ceab85a805a30852f143d22d71c434046fbdbafbc7292e7887cec500826a80", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:poison, "~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []}, "websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []},
} }

View file

@ -0,0 +1 @@
.select-field[data-v-71bc6b38]{width:350px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.select-field[data-v-71bc6b38]{width:100%;margin-bottom:5px}}.actions-button[data-v-3850612b]{text-align:left;width:350px;padding:10px}.actions-button-container[data-v-3850612b]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-dropdown[data-v-3850612b]{float:right}.el-icon-edit[data-v-3850612b]{margin-right:5px}.tag-container[data-v-3850612b]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.tag-text[data-v-3850612b]{padding-right:20px}.no-hover[data-v-3850612b]:hover{color:#606266;background-color:#fff;cursor:auto}.el-dialog__body{padding:20px}.create-account-form-item{margin-bottom:20px}.create-account-form-item-without-margin{margin-bottom:0}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.create-user-dialog{width:85%}.create-account-form-item{margin-bottom:20px}.el-dialog__body{padding:20px}}.moderate-user-button{text-align:left;width:200px;padding:10px}.moderate-user-button-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.actions-button{text-align:left;width:350px;padding:10px}.actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 15px 10px}.active-tag{color:#409eff;font-weight:700}.active-tag .el-icon-check{color:#409eff;float:right;margin:7px 0 0 15px}.el-dropdown-link:hover{cursor:pointer;color:#409eff}.create-account>.el-icon-plus{margin-right:5px}.password-reset-token{margin:0 0 14px}.password-reset-token-dialog{width:50%}.reset-password-link{text-decoration:underline}.users-container h1{margin:22px 0 0 15px}.users-container .pagination{margin:25px 0;text-align:center}.users-container .search{width:350px;float:right}.users-container .filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:22px 15px 15px}.users-container .user-count{color:grey;font-size:28px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.password-reset-token-dialog{width:85%}.users-container h1{margin:7px 10px 15px}.users-container .actions-button{width:100%}.users-container .actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 10px 7px}.users-container .el-icon-arrow-down{font-size:12px}.users-container .search{width:100%}.users-container .filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:82px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 10px}.users-container .el-tag{width:30px;display:inline-block;margin-bottom:4px;font-weight:700}.users-container .el-tag.el-tag--danger,.users-container .el-tag.el-tag--success{padding-left:8px}}

View file

@ -1 +0,0 @@
.actions-button[data-v-56aa3725]{text-align:left;width:350px;padding:10px}.actions-button-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-dropdown[data-v-56aa3725]{float:right}.el-icon-edit[data-v-56aa3725]{margin-right:5px}.tag-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.tag-text[data-v-56aa3725]{padding-right:20px}.no-hover[data-v-56aa3725]:hover{color:#606266;background-color:#fff;cursor:auto}.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-card{margin-bottom:15px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.statuses-container{padding:0 15px}.statuses-container .status-container{margin:0 0 10px}.filter-container{margin:22px 15px 15px 0}.statuses-pagination{padding:15px 0;text-align:center}h1{margin:22px 0 0}

View file

@ -1 +0,0 @@
.wscn-http404-container[data-v-1d6b2d2a]{-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);position:absolute;top:40%;left:50%}.wscn-http404[data-v-1d6b2d2a]{position:relative;width:1200px;padding:0 50px;overflow:hidden}.wscn-http404 .pic-404[data-v-1d6b2d2a]{position:relative;float:left;width:600px;overflow:hidden}.wscn-http404 .pic-404__parent[data-v-1d6b2d2a]{width:100%}.wscn-http404 .pic-404__child[data-v-1d6b2d2a]{position:absolute}.wscn-http404 .pic-404__child.left[data-v-1d6b2d2a]{width:80px;top:17px;left:220px;opacity:0;-webkit-animation-name:cloudLeft-data-v-1d6b2d2a;animation-name:cloudLeft-data-v-1d6b2d2a;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1s;animation-delay:1s}.wscn-http404 .pic-404__child.mid[data-v-1d6b2d2a]{width:46px;top:10px;left:420px;opacity:0;-webkit-animation-name:cloudMid-data-v-1d6b2d2a;animation-name:cloudMid-data-v-1d6b2d2a;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1.2s;animation-delay:1.2s}.wscn-http404 .pic-404__child.right[data-v-1d6b2d2a]{width:62px;top:100px;left:500px;opacity:0;-webkit-animation-name:cloudRight-data-v-1d6b2d2a;animation-name:cloudRight-data-v-1d6b2d2a;-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-delay:1s;animation-delay:1s}@-webkit-keyframes cloudLeft-data-v-1d6b2d2a{0%{top:17px;left:220px;opacity:0}20%{top:33px;left:188px;opacity:1}80%{top:81px;left:92px;opacity:1}to{top:97px;left:60px;opacity:0}}@keyframes cloudLeft-data-v-1d6b2d2a{0%{top:17px;left:220px;opacity:0}20%{top:33px;left:188px;opacity:1}80%{top:81px;left:92px;opacity:1}to{top:97px;left:60px;opacity:0}}@-webkit-keyframes cloudMid-data-v-1d6b2d2a{0%{top:10px;left:420px;opacity:0}20%{top:40px;left:360px;opacity:1}70%{top:130px;left:180px;opacity:1}to{top:160px;left:120px;opacity:0}}@keyframes cloudMid-data-v-1d6b2d2a{0%{top:10px;left:420px;opacity:0}20%{top:40px;left:360px;opacity:1}70%{top:130px;left:180px;opacity:1}to{top:160px;left:120px;opacity:0}}@-webkit-keyframes cloudRight-data-v-1d6b2d2a{0%{top:100px;left:500px;opacity:0}20%{top:120px;left:460px;opacity:1}80%{top:180px;left:340px;opacity:1}to{top:200px;left:300px;opacity:0}}@keyframes cloudRight-data-v-1d6b2d2a{0%{top:100px;left:500px;opacity:0}20%{top:120px;left:460px;opacity:1}80%{top:180px;left:340px;opacity:1}to{top:200px;left:300px;opacity:0}}.wscn-http404 .bullshit[data-v-1d6b2d2a]{position:relative;float:left;width:300px;padding:30px 0;overflow:hidden}.wscn-http404 .bullshit__oops[data-v-1d6b2d2a]{font-size:32px;line-height:40px;color:#1482f0;margin-bottom:20px;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__headline[data-v-1d6b2d2a],.wscn-http404 .bullshit__oops[data-v-1d6b2d2a]{font-weight:700;opacity:0;-webkit-animation-name:slideUp-data-v-1d6b2d2a;animation-name:slideUp-data-v-1d6b2d2a;-webkit-animation-duration:.5s;animation-duration:.5s}.wscn-http404 .bullshit__headline[data-v-1d6b2d2a]{font-size:20px;line-height:24px;color:#222;margin-bottom:10px;-webkit-animation-delay:.1s;animation-delay:.1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__info[data-v-1d6b2d2a]{font-size:13px;line-height:21px;color:grey;margin-bottom:30px;-webkit-animation-delay:.2s;animation-delay:.2s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.wscn-http404 .bullshit__info[data-v-1d6b2d2a],.wscn-http404 .bullshit__return-home[data-v-1d6b2d2a]{opacity:0;-webkit-animation-name:slideUp-data-v-1d6b2d2a;animation-name:slideUp-data-v-1d6b2d2a;-webkit-animation-duration:.5s;animation-duration:.5s}.wscn-http404 .bullshit__return-home[data-v-1d6b2d2a]{display:block;float:left;width:165px;height:36px;background:#1482f0;border-radius:100px;text-align:center;color:#fff;font-size:14px;line-height:36px;cursor:pointer;-webkit-animation-delay:.3s;animation-delay:.3s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@-webkit-keyframes slideUp-data-v-1d6b2d2a{0%{-webkit-transform:translateY(60px);transform:translateY(60px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes slideUp-data-v-1d6b2d2a{0%{-webkit-transform:translateY(60px);transform:translateY(60px);opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}

View file

@ -1 +0,0 @@
.errPage-container[data-v-ab9be52c]{width:800px;max-width:100%;margin:100px auto}.errPage-container .pan-back-btn[data-v-ab9be52c]{background:#008489;color:#fff;border:none!important}.errPage-container .pan-gif[data-v-ab9be52c]{margin:0 auto;display:block}.errPage-container .pan-img[data-v-ab9be52c]{display:block;margin:0 auto;width:100%}.errPage-container .text-jumbo[data-v-ab9be52c]{font-size:60px;font-weight:700;color:#484848}.errPage-container .list-unstyled[data-v-ab9be52c]{font-size:14px}.errPage-container .list-unstyled li[data-v-ab9be52c]{padding-bottom:5px}.errPage-container .list-unstyled a[data-v-ab9be52c]{color:#008489;text-decoration:none}.errPage-container .list-unstyled a[data-v-ab9be52c]:hover{text-decoration:underline}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
.actions-button[data-v-56aa3725]{text-align:left;width:350px;padding:10px}.actions-button-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-dropdown[data-v-56aa3725]{float:right}.el-icon-edit[data-v-56aa3725]{margin-right:5px}.tag-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.tag-text[data-v-56aa3725]{padding-right:20px}.no-hover[data-v-56aa3725]:hover{color:#606266;background-color:#fff;cursor:auto}.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-card{margin-bottom:15px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.statuses-container{padding:0 15px}.statuses-container .status-container{margin:0 0 10px}.filter-container{margin:22px 15px 15px 0}.statuses-pagination{padding:15px 0;text-align:center}h1{margin:22px 0 0}

View file

@ -1 +0,0 @@
.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-card{margin-bottom:15px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}header[data-v-4f90b4f8]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;margin:22px 0;padding-left:15px}header h1[data-v-4f90b4f8]{margin:0 0 0 10px}table[data-v-4f90b4f8]{margin:10px 0 0 15px}table .name-col[data-v-4f90b4f8]{width:150px}.el-table--border[data-v-4f90b4f8]:after,.el-table--group[data-v-4f90b4f8]:after,.el-table[data-v-4f90b4f8]:before{background-color:transparent}.poll ul[data-v-4f90b4f8]{list-style-type:none;padding:0;width:30%}.image[data-v-4f90b4f8]{width:20%}.image img[data-v-4f90b4f8]{width:100%}.no-statuses[data-v-4f90b4f8]{margin-left:28px;color:#606266}.recent-statuses-header[data-v-4f90b4f8]{margin-top:10px}.statuses[data-v-4f90b4f8]{padding:0 20px 0 0}.show-private[data-v-4f90b4f8]{text-align:right;line-height:67px;padding-right:20px}.recent-statuses[data-v-4f90b4f8]{margin-left:28px}.user-profile-card[data-v-4f90b4f8]{margin-left:15px;margin-right:20px}.user-profile-table[data-v-4f90b4f8]{margin:0}.user-profile-tag[data-v-4f90b4f8]{margin:0 4px 4px 0}

View file

@ -1 +0,0 @@
.invites-container .actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:20px 15px 15px}.invites-container .create-invite-token{text-align:left;width:350px;padding:10px}.invites-container .create-new-token-dialog{width:40%}.invites-container .el-dialog__body{padding:5px 20px 0}.invites-container h1{margin:22px 0 0 15px}.invites-container .icon{margin-right:5px}.invites-container .invite-token-table{width:100%;margin:0 15px}.invites-container .invite-via-email{text-align:left;width:350px;padding:10px}.invites-container .invite-via-email-dialog{width:50%}.invites-container .info{color:#666;font-size:13px;line-height:22px;margin:0 0 10px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.invites-container .actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:82px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:15px 10px 7px}.invites-container .create-invite-token{width:100%}.invites-container .create-new-token-dialog{width:85%}.invites-container .el-date-editor{width:150px}.invites-container .el-dialog__body{padding:5px 15px 0}.invites-container h1{margin:7px 10px 15px}.invites-container .invite-token-table{width:100%;margin:0}.invites-container .invite-via-email{width:100%;margin:10px 0 0}.invites-container .invite-via-email-dialog{width:85%}.invites-container .info{margin:0 0 10px 5px}.create-invite-token,.invite-via-email{width:100%}}

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
a{text-decoration:underline}.code{background-color:rgba(173,190,214,.48);border-radius:3px;font-family:monospace;padding:0 3px}.description{font-size:14px;color:#606266;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei;font-weight:700;line-height:20px;margin:0 0 14px}.description-container{overflow-wrap:break-word;margin-bottom:0}.el-form-item{margin-right:30px}.el-form-item .rate-limit{margin-right:0}.center-label label{text-align:center}.el-input-group__prepend{padding-left:10px;padding-right:10px}.el-select{width:100%}.esshd-list{margin:0}.expl{color:#666;font-size:13px;line-height:22px;margin:5px 0 0;overflow-wrap:break-word}.highlight{background-color:#e6e6e6}.icons-button-container{width:100%;margin-bottom:10px}.icons-button-desc{font-size:14px;color:#606266;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei;margin-left:5px}.icon-container{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:95%}.icon-values-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin:0 10px 10px 0}.icon-key-input{width:30%;margin-right:8px}.icon-minus-button{width:36px;height:36px}.icon-value-input{width:70%;margin-left:8px}.icons-container{display:-webkit-box;display:-ms-flexbox;display:flex}.keyword-inner-input{margin-bottom:22px}label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.limit-button-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.limit-expl{margin-left:10px}.limit-input{width:47%;margin:0 0 5px 1%}.mascot-container{margin-bottom:15px}.mascot-input{margin-bottom:7px}.mascot-name-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:7px}.mascot-name-input{margin-right:10px}.name-input{width:30%;margin-right:8px}.pattern-input{width:20%;margin-right:8px}.proxy-url-value-input{width:35%;margin-left:8px;margin-right:10px}.replacement-input{width:80%;margin-left:8px;margin-right:10px}.scale-input{width:47%;margin:0 1% 5px 0}.setting-input{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:10px}.single-input{margin-right:10px}.ssl-tls-opts{margin:36px 0 0}.value-input{width:70%;margin-left:8px;margin-right:10px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-form-item{margin-right:15px}.el-input__inner{padding:0 5px}.el-form-item__label:not(.no-top-margin){padding-left:3px;padding-right:10px;line-height:22px;margin-top:7px}.el-message{min-width:80%}.el-select__tags{overflow:hidden}.name-input{width:40%;margin-right:5px}p.expl{line-height:20px}.pattern-input{width:40%;margin-right:4px}.replacement-input{width:60%;margin-left:4px;margin-right:5px}.top-margin{position:absolute;top:25%}.value-input{width:60%;margin-left:5px;margin-right:8px}}.copy-popover{width:330px}.emoji-button{margin-left:10px}.emoji-buttons{min-width:210px}.emoji-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:10px}.emoji-preview-img{max-width:5em}.emoji-info{margin-left:10px}.copy-to-local-button{margin-top:12px;float:right}.add-new-emoji{height:36px;font-size:14px;font-weight:700;color:#606266}.text{line-height:20px;margin-right:15px}.upload-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.upload-button{margin-left:10px}.upload-file-url{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.download-archive{width:250px}.download-shared-pack{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:10px}.download-shared-pack-button{margin-left:10px}.el-collapse-item__content{padding-bottom:0}.el-collapse-item__header{height:36px;font-size:14px;font-weight:700;color:#606266}.emoji-pack-card{margin-top:5px}.emoji-pack-metadata .el-form-item{margin-bottom:10px}.has-background .el-collapse-item__header{background:#f6f6f6}.no-background .el-collapse-item__header{background:#fff}.save-pack-button{margin-bottom:5px}.button-container{margin:0 0 22px 20px}.create-pack{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.create-pack-button{margin-left:10px}.line{width:100%;height:0;border:1px solid #eee;margin-bottom:22px}.settings-container .el-tabs[data-v-6c80d30e]{margin-top:20px}.settings-container h1[data-v-6c80d30e]{margin:22px 0 0 15px}

View file

@ -1 +0,0 @@
.select-field[data-v-71bc6b38]{width:350px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.select-field[data-v-71bc6b38]{width:100%;margin-bottom:5px}}.actions-button[data-v-56aa3725]{text-align:left;width:350px;padding:10px}.actions-button-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-dropdown[data-v-56aa3725]{float:right}.el-icon-edit[data-v-56aa3725]{margin-right:5px}.tag-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.tag-text[data-v-56aa3725]{padding-right:20px}.no-hover[data-v-56aa3725]:hover{color:#606266;background-color:#fff;cursor:auto}.el-dialog__body{padding:20px}.create-account-form-item{margin-bottom:20px}.create-account-form-item-without-margin{margin-bottom:0}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.create-user-dialog{width:85%}.create-account-form-item{margin-bottom:20px}.el-dialog__body{padding:20px}}.actions-button{text-align:left;width:350px;padding:10px}.actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 15px 10px}.active-tag{color:#409eff;font-weight:700}.active-tag .el-icon-check{color:#409eff;float:right;margin:7px 0 0 15px}.el-dropdown-link:hover{cursor:pointer;color:#409eff}.el-icon-plus{margin-right:5px}.password-reset-token{margin:0 0 14px}.password-reset-token-dialog{width:50%}.reset-password-link{text-decoration:underline}.users-container h1{margin:22px 0 0 15px}.users-container .pagination{margin:25px 0;text-align:center}.users-container .search{width:350px;float:right}.users-container .filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:22px 15px 15px}.users-container .user-count{color:grey;font-size:28px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.password-reset-token-dialog{width:85%}.users-container h1{margin:7px 10px 15px}.users-container .actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 10px 7px}.users-container .create-account{width:100%}.users-container .el-icon-arrow-down{font-size:12px}.users-container .search{width:100%}.users-container .filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:82px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 10px}.users-container .el-tag{width:30px;display:inline-block;margin-bottom:4px;font-weight:700}.users-container .el-tag.el-tag--danger,.users-container .el-tag.el-tag--success{padding-left:8px}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
.moderation-log-container[data-v-74b48266]{margin:0 15px}h1[data-v-74b48266]{margin:22px 0 20px}.el-timeline[data-v-74b48266]{margin:25px 45px 0 0;padding:0}.user-select[data-v-74b48266]{margin:0 0 20px;width:350px}.search-container[data-v-74b48266]{text-align:right}.pagination[data-v-74b48266]{text-align:center}

View file

@ -1 +0,0 @@
@supports (-webkit-mask:none) and (not (cater-color:#fff)){.login-container .el-input input{color:#fff}.login-container .el-input input:first-line{color:#eee}}.login-container .el-input{display:inline-block;height:47px;width:85%}.login-container .el-input input{background:transparent;border:0;-webkit-appearance:none;border-radius:0;padding:12px 5px 12px 15px;color:#eee;height:47px;caret-color:#fff}.login-container .el-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #283443 inset!important;-webkit-text-fill-color:#fff!important}.login-container .el-form-item{border:1px solid hsla(0,0%,100%,.1);background:rgba(0,0,0,.1);border-radius:5px;color:#454545}.login-container .login-button{width:100%;margin:0 0 10px}.login-container .omit-host-note{color:#596f8c;font-size:.8em;font-style:italic;margin:-20px 0 15px;padding:3px 0 0 15px}.login-container[data-v-5bb13616]{min-height:100%;width:100%;background-color:#2d3a4b;overflow:hidden}.login-container .login-form[data-v-5bb13616]{position:relative;width:520px;max-width:100%;padding:160px 35px 0;margin:0 auto;overflow:hidden}.login-container .tips[data-v-5bb13616]{font-size:14px;color:#fff;margin-bottom:10px}.login-container .tips span[data-v-5bb13616]:first-of-type{margin-right:16px}.login-container .svg-container[data-v-5bb13616]{padding:6px 5px 6px 15px;color:#889aa4;vertical-align:middle;width:30px;display:inline-block}.login-container .title-container[data-v-5bb13616]{position:relative}.login-container .title-container .title[data-v-5bb13616]{font-size:26px;color:#eee;margin:0 auto 40px;text-align:center;font-weight:700}.login-container .title-container .set-language[data-v-5bb13616]{color:#fff;position:absolute;top:3px;font-size:18px;right:0;cursor:pointer}.login-container .show-pwd[data-v-5bb13616]{position:absolute;right:10px;top:7px;font-size:16px;color:#889aa4;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.login-container .thirdparty-button[data-v-5bb13616]{position:absolute;right:0;bottom:6px}

View file

@ -1 +0,0 @@
.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-card{margin-bottom:15px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}header[data-v-1966c214]{-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-ms-flexbox;display:flex;margin:22px 0;padding-left:15px}header h1[data-v-1966c214]{margin:0 0 0 10px}table[data-v-1966c214]{margin:10px 0 0 15px}table .name-col[data-v-1966c214]{width:150px}.el-table--border[data-v-1966c214]:after,.el-table--group[data-v-1966c214]:after,.el-table[data-v-1966c214]:before{background-color:transparent}.poll ul[data-v-1966c214]{list-style-type:none;padding:0;width:30%}.image[data-v-1966c214]{width:20%}.image img[data-v-1966c214]{width:100%}.no-statuses[data-v-1966c214]{margin-left:28px;color:#606266}.recent-statuses-header[data-v-1966c214]{margin-top:10px}.statuses[data-v-1966c214]{padding:0 20px 0 0}.show-private[data-v-1966c214]{text-align:right;line-height:67px;padding-right:20px}.recent-statuses[data-v-1966c214]{margin-left:28px}.user-profile-card[data-v-1966c214]{margin-left:15px;margin-right:20px}.user-profile-table[data-v-1966c214]{margin:0}.user-profile-tag[data-v-1966c214]{margin:0 4px 4px 0}

View file

@ -0,0 +1 @@
.status-card{margin-bottom:10px}.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-checkbox{margin-right:7px}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.moderate-user-button{text-align:left;width:200px;padding:10px}.moderate-user-button-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.avatar-name-container[data-v-c2753c94],header[data-v-c2753c94]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}header[data-v-c2753c94]{margin:22px 0;padding-left:15px}header h1[data-v-c2753c94]{margin:0 0 0 10px}table[data-v-c2753c94]{margin:10px 0 0 15px}table .name-col[data-v-c2753c94]{width:150px}.el-table--border[data-v-c2753c94]:after,.el-table--group[data-v-c2753c94]:after,.el-table[data-v-c2753c94]:before{background-color:transparent}.poll ul[data-v-c2753c94]{list-style-type:none;padding:0;width:30%}.image[data-v-c2753c94]{width:20%}.image img[data-v-c2753c94]{width:100%}.no-statuses[data-v-c2753c94]{margin-left:28px;color:#606266}.recent-statuses-header[data-v-c2753c94]{margin-top:10px}.statuses[data-v-c2753c94]{padding:0 20px 0 0}.show-private[data-v-c2753c94]{width:200px;text-align:left;line-height:67px;margin-right:20px}.recent-statuses[data-v-c2753c94]{margin-left:28px}.user-page-header[data-v-c2753c94]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:0 20px}.user-page-header h1[data-v-c2753c94]{display:inline}.user-profile-card[data-v-c2753c94]{margin:0 20px}.user-profile-table[data-v-c2753c94]{margin:0}.user-profile-tag[data-v-c2753c94]{margin:0 4px 4px 0}

View file

@ -0,0 +1 @@
.copy-popover{width:330px}.emoji-buttons{place-self:center;min-width:200px}.emoji-container{display:grid;grid-template-columns:75px auto auto 195px;grid-column-gap:15px;margin-bottom:10px}.emoji-preview-img{max-width:100%;place-self:center}.emoji-info{place-self:center}.copy-to-local-button{margin-top:12px;float:right}.add-new-emoji{height:36px;font-size:14px;font-weight:700;color:#606266}.text{line-height:20px;margin-right:15px}.upload-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.upload-button{margin-left:10px}.upload-file-url{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.download-archive{width:250px}.download-shared-pack{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:10px}.download-shared-pack-button{margin-left:10px}.el-collapse-item__content{padding-bottom:0}.el-collapse-item__header{height:36px;font-size:14px;font-weight:700;color:#606266}.emoji-pack-card{margin-top:5px}.emoji-pack-metadata .el-form-item{margin-bottom:10px}.has-background .el-collapse-item__header{background:#f6f6f6}.no-background .el-collapse-item__header{background:#fff}.save-pack-button{margin-bottom:5px}.button-container{margin:0 0 22px 15px}.create-pack{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.create-pack-button{margin-left:10px}.emoji-packs-form{margin:0 30px}.emoji-packs-header{margin:22px 0 20px 15px}.line{width:100%;height:0;border:1px solid #eee;margin-bottom:22px}@media only screen and (min-width:1824px){.emoji-packs{max-width:1824px;margin:auto}}

View file

@ -0,0 +1 @@
.actions-button[data-v-3850612b]{text-align:left;width:350px;padding:10px}.actions-button-container[data-v-3850612b]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-dropdown[data-v-3850612b]{float:right}.el-icon-edit[data-v-3850612b]{margin-right:5px}.tag-container[data-v-3850612b]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.tag-text[data-v-3850612b]{padding-right:20px}.no-hover[data-v-3850612b]:hover{color:#606266;background-color:#fff;cursor:auto}.status-card{margin-bottom:10px}.status-card .account{text-decoration:underline;line-height:26px;font-size:13px}.status-card .image{width:20%}.status-card .image img{width:100%}.status-card .show-more-button{margin-left:5px}.status-card .status-account{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.status-card .status-avatar-img{display:inline-block;width:15px;height:15px;margin-right:5px}.status-card .status-account-name{display:inline-block;margin:0;height:22px}.status-card .status-body{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.status-card .status-checkbox{margin-right:7px}.status-card .status-content{font-size:15px;line-height:26px}.status-card .status-deleted{font-style:italic;margin-top:3px}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.status-card .status-without-content{font-style:italic}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-message{min-width:80%}.el-message-box{width:80%}.status-card .el-card__header{padding:10px 17px}.status-card .el-tag{margin:3px 4px 3px 0}.status-card .status-account-container{margin-bottom:5px}.status-card .status-actions-button{margin:3px 0}.status-card .status-actions{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.status-card .status-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.statuses-container{padding:0 15px}.statuses-container .status-container{margin:0 0 10px}.filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:22px 0 15px}.select-instance{width:350px}.statuses-pagination{padding:15px 0;text-align:center}h1{margin:22px 0 0}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:10px}.select-field{width:100%;margin-bottom:5px}}

View file

@ -1 +0,0 @@
.select-field[data-v-71bc6b38]{width:350px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.select-field[data-v-71bc6b38]{width:100%;margin-bottom:5px}}.actions-button[data-v-56aa3725]{text-align:left;width:350px;padding:10px}.actions-button-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.el-dropdown[data-v-56aa3725]{float:right}.el-icon-edit[data-v-56aa3725]{margin-right:5px}.tag-container[data-v-56aa3725]{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.tag-text[data-v-56aa3725]{padding-right:20px}.no-hover[data-v-56aa3725]:hover{color:#606266;background-color:#fff;cursor:auto}.el-dialog__body{padding:20px}.create-account-form-item{margin-bottom:20px}.create-account-form-item-without-margin{margin-bottom:0}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.create-user-dialog{width:85%}.create-account-form-item{margin-bottom:20px}.el-dialog__body{padding:20px}}.actions-button{text-align:left;width:350px;padding:10px}.actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0 15px 10px}.active-tag{color:#409eff;font-weight:700}.active-tag .el-icon-check{color:#409eff;float:right;margin:7px 0 0 15px}.el-dropdown-link:hover{cursor:pointer;color:#409eff}.el-icon-plus{margin-right:5px}.password-reset-token{margin:0 0 14px}.password-reset-token-dialog{width:50%}.reset-password-link{text-decoration:underline}.users-container h1{margin:22px 0 0 15px}.users-container .pagination{margin:25px 0;text-align:center}.users-container .search{width:350px;float:right}.users-container .filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:36px;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:22px 15px 15px}.users-container .user-count{color:grey;font-size:28px}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.password-reset-token-dialog{width:85%}.users-container h1{margin:7px 10px 15px}.users-container .actions-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 10px 7px}.users-container .create-account{width:100%}.users-container .el-icon-arrow-down{font-size:12px}.users-container .search{width:100%}.users-container .filter-container{display:-webkit-box;display:-ms-flexbox;display:flex;height:82px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin:0 10px}.users-container .el-tag{width:30px;display:inline-block;margin-bottom:4px;font-weight:700}.users-container .el-tag.el-tag--danger,.users-container .el-tag.el-tag--success{padding-left:8px}}

View file

@ -1 +0,0 @@
a{text-decoration:underline}.code{background-color:rgba(173,190,214,.48);border-radius:3px;font-family:monospace;padding:0 3px}.el-form-item{margin-right:30px}.el-select{width:100%}.esshd-list{margin:0}.expl{color:#666;font-size:13px;line-height:22px;margin:5px 0 0;overflow-wrap:break-word}.highlight{background-color:#e6e6e6}.limit-button-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.limit-expl{margin-left:10px}.limit-input{width:48%;margin:0 0 5px 8px}.mascot-container{margin-bottom:15px}.mascot-input{margin-bottom:7px}.mascot-name-container{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:7px}.mascot-name-input{margin-right:10px}.name-input{width:30%;margin-right:8px}.options-paragraph{font-size:14px;color:#606266;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei;font-weight:700;line-height:20px;margin:0 0 14px}.options-paragraph-container{overflow-wrap:break-word;margin-bottom:0}.pattern-input{width:20%;margin-right:8px}.setting-input{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:10px}.single-input{margin-right:10px}.scale-input{width:48%;margin:0 8px 5px 0}.replacement-input{width:80%}.replacement-input,.value-input{margin-left:8px;margin-right:10px}.value-input{width:70%}@media (min-device-width:768px) and (max-device-width:1024px),only screen and (max-width:760px){.el-form-item{margin-right:15px}.el-input__inner{padding:0 5px}.el-form-item__label:not(.no-top-margin){padding-left:3px;padding-right:10px;line-height:22px;margin-top:7px}.el-message{min-width:80%}.el-select__tags{overflow:hidden}.name-input{width:40%;margin-right:5px}p.expl{line-height:20px}.pattern-input{width:40%;margin-right:4px}.replacement-input{width:60%;margin-left:4px;margin-right:5px}.top-margin{position:absolute;top:25%}.value-input{width:60%;margin-left:5px;margin-right:8px}}.copy-popover{width:330px}.emoji-button{margin-left:10px}.emoji-buttons{min-width:210px}.emoji-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:10px}.emoji-preview-img{max-width:5em}.emoji-info{margin-left:10px}.copy-to-local-button{margin-top:12px;float:right}.add-new-emoji{height:36px;font-size:14px;font-weight:700;color:#606266}.text{line-height:20px;margin-right:15px}.upload-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.upload-button{margin-left:10px}.upload-file-url{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.download-archive{width:250px}.download-shared-pack{display:-webkit-box;display:-ms-flexbox;display:flex;margin-bottom:10px}.download-shared-pack-button{margin-left:10px}.el-collapse-item__content{padding-bottom:0}.el-collapse-item__header{height:36px;font-size:14px;font-weight:700;color:#606266}.emoji-pack-card{margin-top:5px}.emoji-pack-metadata .el-form-item{margin-bottom:10px}.has-background .el-collapse-item__header{background:#f6f6f6}.no-background .el-collapse-item__header{background:#fff}.save-pack-button{margin-bottom:5px}.button-container{margin:0 0 22px 20px}.create-pack{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.create-pack-button{margin-left:10px}.line{width:100%;height:0;border:1px solid #eee;margin-bottom:22px}.settings-container .el-tabs[data-v-c56a6d00]{margin-top:20px}.settings-container h1[data-v-c56a6d00]{margin:22px 0 0 15px}

View file

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.57fe98a3.css rel=stylesheet><link href=app.fdd73ce4.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.cab03b3e.js></script><script type=text/javascript src=static/js/chunk-elementUI.2de79b84.js></script><script type=text/javascript src=static/js/chunk-libs.680db3fc.js></script><script type=text/javascript src=static/js/app.3da0f475.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.686b5876.css rel=stylesheet><link href=app.c836e084.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.dfdeb6eb.js></script><script type=text/javascript src=static/js/chunk-elementUI.fba0efec.js></script><script type=text/javascript src=static/js/chunk-libs.b8c453ab.js></script><script type=text/javascript src=static/js/app.5f0094e3.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show more