Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remove-twitter-api

This commit is contained in:
lain 2020-07-06 12:15:59 +02:00
commit 1963e143c5
82 changed files with 1163 additions and 238 deletions

View file

@ -14,7 +14,7 @@
* Pleroma version (could be found in the "Version" tab of settings in Pleroma-FE): * Pleroma version (could be found in the "Version" tab of settings in Pleroma-FE):
* Elixir version (`elixir -v` for from source installations, N/A for OTP): * Elixir version (`elixir -v` for from source installations, N/A for OTP):
* Operating system: * Operating system:
* PostgreSQL version (`postgres -V`): * PostgreSQL version (`psql -V`):
### Bug description ### Bug description

View file

@ -17,6 +17,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
<summary>API Changes</summary> <summary>API Changes</summary>
- **Breaking:** Emoji API: changed methods and renamed routes. - **Breaking:** Emoji API: changed methods and renamed routes.
- Streaming: Repeats of a user's posts will no longer be pushed to the user's stream.
- Mastodon API: Added `pleroma.metadata.fields_limits` to /api/v1/instance
- Mastodon API: On deletion, returns the original post text.
</details> </details>
<details> <details>

View file

@ -40,12 +40,13 @@
key: :link_name, key: :link_name,
type: :boolean, type: :boolean,
description: description:
"If enabled, a name parameter will be added to the url of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`." "If enabled, a name parameter will be added to the URL of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`."
}, },
%{ %{
key: :base_url, key: :base_url,
label: "Base URL",
type: :string, type: :string,
description: "Base url for the uploads, needed if you use CDN", description: "Base URL for the uploads, needed if you use CDN",
suggestions: [ suggestions: [
"https://cdn-host.com" "https://cdn-host.com"
] ]
@ -58,6 +59,7 @@
}, },
%{ %{
key: :proxy_opts, key: :proxy_opts,
label: "Proxy Options",
type: :keyword, type: :keyword,
description: "Options for Pleroma.ReverseProxy", description: "Options for Pleroma.ReverseProxy",
suggestions: [ suggestions: [
@ -85,6 +87,7 @@
}, },
%{ %{
key: :http, key: :http,
label: "HTTP",
type: :keyword, type: :keyword,
description: "HTTP options", description: "HTTP options",
children: [ children: [
@ -193,7 +196,9 @@
%{ %{
key: :args, key: :args,
type: [:string, {:list, :string}, {:list, :tuple}], type: [:string, {:list, :string}, {:list, :tuple}],
description: "List of actions for the mogrify command", description:
"List of actions for the mogrify command. It's possible to add self-written settings as string. " <>
"For example `[\"auto-orient\", \"strip\", {\"resize\", \"3840x1080>\"}]` string will be parsed into list of the settings.",
suggestions: [ suggestions: [
"strip", "strip",
"auto-orient", "auto-orient",
@ -479,6 +484,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :uri_schemes, key: :uri_schemes,
label: "URI Schemes",
type: :group, type: :group,
description: "URI schemes related settings", description: "URI schemes related settings",
children: [ children: [
@ -651,17 +657,17 @@
key: :invites_enabled, key: :invites_enabled,
type: :boolean, type: :boolean,
description: description:
"Enable user invitations for admins (depends on `registrations_open` being disabled)." "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,
@ -679,7 +685,7 @@
label: "Fed. reachability timeout days", label: "Fed. reachability timeout days",
type: :integer, type: :integer,
description: description:
"Timeout (in days) of each external federation target being unreachable prior to pausing federating to it.", "Timeout (in days) of each external federation target being unreachable prior to pausing federating to it",
suggestions: [ suggestions: [
7 7
] ]
@ -801,6 +807,7 @@
}, },
%{ %{
key: :safe_dm_mentions, key: :safe_dm_mentions,
label: "Safe DM mentions",
type: :boolean, type: :boolean,
description: description:
"If enabled, 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." <>
@ -840,7 +847,7 @@
%{ %{
key: :skip_thread_containment, key: :skip_thread_containment,
type: :boolean, type: :boolean,
description: "Skip filtering out broken threads. Default: enabled" description: "Skip filtering out broken threads. Default: enabled."
}, },
%{ %{
key: :limit_to_local_content, key: :limit_to_local_content,
@ -904,6 +911,7 @@
children: [ children: [
%{ %{
key: :totp, key: :totp,
label: "TOTP settings",
type: :keyword, type: :keyword,
description: "TOTP settings", description: "TOTP settings",
suggestions: [digits: 6, period: 30], suggestions: [digits: 6, period: 30],
@ -920,7 +928,7 @@
type: :integer, type: :integer,
suggestions: [30], suggestions: [30],
description: description:
"a period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds." "A period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds."
} }
] ]
}, },
@ -934,7 +942,7 @@
key: :number, key: :number,
type: :integer, type: :integer,
suggestions: [5], suggestions: [5],
description: "number of backup codes to generate." description: "Number of backup codes to generate."
}, },
%{ %{
key: :length, key: :length,
@ -974,6 +982,7 @@
group: :logger, group: :logger,
type: :group, type: :group,
key: :ex_syslogger, key: :ex_syslogger,
label: "ExSyslogger",
description: "ExSyslogger-related settings", description: "ExSyslogger-related settings",
children: [ children: [
%{ %{
@ -992,7 +1001,7 @@
%{ %{
key: :format, key: :format,
type: :string, type: :string,
description: "Default: \"$date $time [$level] $levelpad$node $metadata $message\".", description: "Default: \"$date $time [$level] $levelpad$node $metadata $message\"",
suggestions: ["$metadata[$level] $message"] suggestions: ["$metadata[$level] $message"]
}, },
%{ %{
@ -1006,6 +1015,7 @@
group: :logger, group: :logger,
type: :group, type: :group,
key: :console, key: :console,
label: "Console Logger",
description: "Console logger settings", description: "Console logger settings",
children: [ children: [
%{ %{
@ -1017,7 +1027,7 @@
%{ %{
key: :format, key: :format,
type: :string, type: :string,
description: "Default: \"$date $time [$level] $levelpad$node $metadata $message\".", description: "Default: \"$date $time [$level] $levelpad$node $metadata $message\"",
suggestions: ["$metadata[$level] $message"] suggestions: ["$metadata[$level] $message"]
}, },
%{ %{
@ -1030,6 +1040,7 @@
%{ %{
group: :quack, group: :quack,
type: :group, type: :group,
label: "Quack Logger",
description: "Quack-related settings", description: "Quack-related settings",
children: [ children: [
%{ %{
@ -1140,19 +1151,19 @@
key: :greentext, key: :greentext,
label: "Greentext", label: "Greentext",
type: :boolean, type: :boolean,
description: "Enables green text on lines prefixed with the > character." description: "Enables green text on lines prefixed with the > character"
}, },
%{ %{
key: :hideFilteredStatuses, key: :hideFilteredStatuses,
label: "Hide Filtered Statuses", label: "Hide Filtered Statuses",
type: :boolean, type: :boolean,
description: "Hides filtered statuses from timelines." description: "Hides filtered statuses from timelines"
}, },
%{ %{
key: :hideMutedPosts, key: :hideMutedPosts,
label: "Hide Muted Posts", label: "Hide Muted Posts",
type: :boolean, type: :boolean,
description: "Hides muted statuses from timelines." description: "Hides muted statuses from timelines"
}, },
%{ %{
key: :hidePostStats, key: :hidePostStats,
@ -1164,7 +1175,7 @@
key: :hideSitename, key: :hideSitename,
label: "Hide Sitename", label: "Hide Sitename",
type: :boolean, type: :boolean,
description: "Hides instance name from PleromaFE banner." description: "Hides instance name from PleromaFE banner"
}, },
%{ %{
key: :hideUserStats, key: :hideUserStats,
@ -1209,14 +1220,14 @@
label: "NSFW Censor Image", label: "NSFW Censor Image",
type: :string, type: :string,
description: description:
"URL of the image to use for hiding NSFW media attachments in the timeline.", "URL of the image to use for hiding NSFW media attachments in the timeline",
suggestions: ["/static/img/nsfw.74818f9.png"] suggestions: ["/static/img/nsfw.74818f9.png"]
}, },
%{ %{
key: :postContentType, key: :postContentType,
label: "Post Content Type", label: "Post Content Type",
type: {:dropdown, :atom}, type: {:dropdown, :atom},
description: "Default post formatting option.", description: "Default post formatting option",
suggestions: ["text/plain", "text/html", "text/markdown", "text/bbcode"] suggestions: ["text/plain", "text/html", "text/markdown", "text/bbcode"]
}, },
%{ %{
@ -1245,14 +1256,14 @@
key: :sidebarRight, key: :sidebarRight,
label: "Sidebar on Right", label: "Sidebar on Right",
type: :boolean, type: :boolean,
description: "Change alignment of sidebar and panels to the right." description: "Change alignment of sidebar and panels to the right"
}, },
%{ %{
key: :showFeaturesPanel, key: :showFeaturesPanel,
label: "Show instance features panel", label: "Show instance features panel",
type: :boolean, type: :boolean,
description: description:
"Enables panel displaying functionality of the instance on the About page." "Enables panel displaying functionality of the instance on the About page"
}, },
%{ %{
key: :showInstanceSpecificPanel, key: :showInstanceSpecificPanel,
@ -1310,7 +1321,7 @@
key: :mascots, key: :mascots,
type: {:keyword, :map}, type: {:keyword, :map},
description: description:
"Keyword of mascots, each element must contain both an url and a mime_type key", "Keyword of mascots, each element must contain both an URL and a mime_type key",
suggestions: [ suggestions: [
pleroma_fox_tan: %{ pleroma_fox_tan: %{
url: "/images/pleroma-fox-tan-smol.png", url: "/images/pleroma-fox-tan-smol.png",
@ -1334,7 +1345,7 @@
%{ %{
key: :default_user_avatar, key: :default_user_avatar,
type: :string, type: :string,
description: "URL of the default user avatar.", description: "URL of the default user avatar",
suggestions: ["/images/avi.png"] suggestions: ["/images/avi.png"]
} }
] ]
@ -1344,7 +1355,7 @@
key: :manifest, key: :manifest,
type: :group, type: :group,
description: description:
"This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE", "This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE.",
children: [ children: [
%{ %{
key: :icons, key: :icons,
@ -1380,10 +1391,49 @@
}, },
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_simple, key: :mrf,
label: "MRF simple", tab: :mrf,
label: "MRF",
type: :group, type: :group,
description: "Message Rewrite Facility", description: "General MRF settings",
children: [
%{
key: :policies,
type: [:module, {:list, :module}],
description:
"A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
suggestions:
Generator.list_modules_in_dir(
"lib/pleroma/web/activity_pub/mrf",
"Elixir.Pleroma.Web.ActivityPub.MRF."
)
},
%{
key: :transparency,
label: "MRF transparency",
type: :boolean,
description:
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
},
%{
key: :transparency_exclusions,
label: "MRF transparency exclusions",
type: {:list, :string},
description:
"Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.",
suggestions: [
"exclusion.com"
]
}
]
},
%{
group: :pleroma,
key: :mrf_simple,
tab: :mrf,
label: "MRF Simple",
type: :group,
description: "Simple ingress policies",
children: [ children: [
%{ %{
key: :media_removal, key: :media_removal,
@ -1402,7 +1452,7 @@
key: :federated_timeline_removal, key: :federated_timeline_removal,
type: {:list, :string}, type: {:list, :string},
description: description:
"List of instances to remove from Federated (aka The Whole Known Network) Timeline", "List of instances to remove from the Federated (aka The Whole Known Network) Timeline",
suggestions: ["example.com", "*.example.com"] suggestions: ["example.com", "*.example.com"]
}, },
%{ %{
@ -1446,14 +1496,15 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_activity_expiration, key: :mrf_activity_expiration,
tab: :mrf,
label: "MRF Activity Expiration Policy", label: "MRF Activity Expiration Policy",
type: :group, type: :group,
description: "Adds expiration to all local Create Note activities", description: "Adds automatic expiration to all local activities",
children: [ children: [
%{ %{
key: :days, key: :days,
type: :integer, type: :integer,
description: "Default global expiration time for all local Create activities (in days)", description: "Default global expiration time for all local activities (in days)",
suggestions: [90, 365] suggestions: [90, 365]
} }
] ]
@ -1461,7 +1512,8 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_subchain, key: :mrf_subchain,
label: "MRF subchain", tab: :mrf,
label: "MRF Subchain",
type: :group, type: :group,
description: description:
"This policy processes messages through an alternate pipeline when a given message matches certain criteria." <> "This policy processes messages through an alternate pipeline when a given message matches certain criteria." <>
@ -1482,9 +1534,9 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_rejectnonpublic, key: :mrf_rejectnonpublic,
description: tab: :mrf,
"MRF RejectNonPublic settings. RejectNonPublic drops posts with non-public visibility settings.", description: "RejectNonPublic drops posts with non-public visibility settings.",
label: "MRF reject non public", label: "MRF Reject Non Public",
type: :group, type: :group,
children: [ children: [
%{ %{
@ -1503,16 +1555,17 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_hellthread, key: :mrf_hellthread,
label: "MRF hellthread", tab: :mrf,
label: "MRF Hellthread",
type: :group, type: :group,
description: "Block messages with too much mentions", description: "Block messages with excessive user mentions",
children: [ children: [
%{ %{
key: :delist_threshold, key: :delist_threshold,
type: :integer, type: :integer,
description: description:
"Number of mentioned users after which the message gets delisted (the message can still be seen, " <> "Number of mentioned users after which the message gets removed from timelines and" <>
" but it will not show up in public timelines and mentioned users won't get notifications about it). Set to 0 to disable.", "disables notifications. Set to 0 to disable.",
suggestions: [10] suggestions: [10]
}, },
%{ %{
@ -1527,7 +1580,8 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_keyword, key: :mrf_keyword,
label: "MRF keyword", tab: :mrf,
label: "MRF Keyword",
type: :group, type: :group,
description: "Reject or Word-Replace messages with a keyword or regex", description: "Reject or Word-Replace messages with a keyword or regex",
children: [ children: [
@ -1557,14 +1611,15 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_mention, key: :mrf_mention,
label: "MRF mention", tab: :mrf,
label: "MRF Mention",
type: :group, type: :group,
description: "Block messages which mention a user", description: "Block messages which mention a specific user",
children: [ children: [
%{ %{
key: :actors, key: :actors,
type: {:list, :string}, type: {:list, :string},
description: "A list of actors for which any post mentioning them will be dropped.", description: "A list of actors for which any post mentioning them will be dropped",
suggestions: ["actor1", "actor2"] suggestions: ["actor1", "actor2"]
} }
] ]
@ -1572,7 +1627,8 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_vocabulary, key: :mrf_vocabulary,
label: "MRF vocabulary", tab: :mrf,
label: "MRF Vocabulary",
type: :group, type: :group,
description: "Filter messages which belong to certain activity vocabularies", description: "Filter messages which belong to certain activity vocabularies",
children: [ children: [
@ -1580,14 +1636,14 @@
key: :accept, key: :accept,
type: {:list, :string}, type: {:list, :string},
description: description:
"A list of ActivityStreams terms to accept. If empty, all supported messages are accepted", "A list of ActivityStreams terms to accept. If empty, all supported messages are accepted.",
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"] suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
}, },
%{ %{
key: :reject, key: :reject,
type: {:list, :string}, type: {:list, :string},
description: description:
"A list of ActivityStreams terms to reject. If empty, no messages are rejected", "A list of ActivityStreams terms to reject. If empty, no messages are rejected.",
suggestions: ["Create", "Follow", "Mention", "Announce", "Like"] suggestions: ["Create", "Follow", "Mention", "Announce", "Like"]
} }
] ]
@ -1617,6 +1673,7 @@
}, },
%{ %{
key: :base_url, key: :base_url,
label: "Base URL",
type: :string, type: :string,
description: description:
"The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.", "The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.",
@ -1649,6 +1706,7 @@
}, },
%{ %{
key: :proxy_opts, key: :proxy_opts,
label: "Proxy Options",
type: :keyword, type: :keyword,
description: "Options for Pleroma.ReverseProxy", description: "Options for Pleroma.ReverseProxy",
suggestions: [ suggestions: [
@ -1676,6 +1734,7 @@
}, },
%{ %{
key: :http, key: :http,
label: "HTTP",
type: :keyword, type: :keyword,
description: "HTTP options", description: "HTTP options",
children: [ children: [
@ -1771,6 +1830,7 @@
}, },
%{ %{
key: :ip, key: :ip,
label: "IP",
type: :tuple, type: :tuple,
description: "IP address to bind to", description: "IP address to bind to",
suggestions: [{0, 0, 0, 0}] suggestions: [{0, 0, 0, 0}]
@ -1784,7 +1844,7 @@
%{ %{
key: :dstport, key: :dstport,
type: :integer, type: :integer,
description: "Port advertised in urls (optional, defaults to port)", description: "Port advertised in URLs (optional, defaults to port)",
suggestions: [9999] suggestions: [9999]
} }
] ]
@ -1792,6 +1852,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :activitypub, key: :activitypub,
label: "ActivityPub",
type: :group, type: :group,
description: "ActivityPub-related settings", description: "ActivityPub-related settings",
children: [ children: [
@ -1814,7 +1875,7 @@
key: :note_replies_output_limit, key: :note_replies_output_limit,
type: :integer, type: :integer,
description: description:
"The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)." "The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)"
}, },
%{ %{
key: :follow_handshake_timeout, key: :follow_handshake_timeout,
@ -1827,6 +1888,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :http_security, key: :http_security,
label: "HTTP security",
type: :group, type: :group,
description: "HTTP security settings", description: "HTTP security settings",
children: [ children: [
@ -1865,7 +1927,7 @@
key: :report_uri, key: :report_uri,
label: "Report URI", label: "Report URI",
type: :string, type: :string,
description: "Adds the specified url to report-uri and report-to group in CSP header", description: "Adds the specified URL to report-uri and report-to group in CSP header",
suggestions: ["https://example.com/report-uri"] suggestions: ["https://example.com/report-uri"]
} }
] ]
@ -1873,9 +1935,10 @@
%{ %{
group: :web_push_encryption, group: :web_push_encryption,
key: :vapid_details, key: :vapid_details,
label: "Vapid Details",
type: :group, type: :group,
description: description:
"Web Push Notifications configuration. You can use the mix task mix web_push.gen.keypair to generate it", "Web Push Notifications configuration. You can use the mix task mix web_push.gen.keypair to generate it.",
children: [ children: [
%{ %{
key: :subject, key: :subject,
@ -1942,6 +2005,7 @@
}, },
%{ %{
group: :pleroma, group: :pleroma,
label: "Pleroma Admin Token",
type: :group, type: :group,
description: description:
"Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the `admin_token` parameter", "Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the `admin_token` parameter",
@ -1949,7 +2013,7 @@
%{ %{
key: :admin_token, key: :admin_token,
type: :string, type: :string,
description: "Token", description: "Admin token",
suggestions: ["We recommend a secure random string or UUID"] suggestions: ["We recommend a secure random string or UUID"]
} }
] ]
@ -2114,24 +2178,24 @@
key: :rich_media, key: :rich_media,
type: :group, type: :group,
description: description:
"If enabled the instance will parse metadata from attached links to generate link previews.", "If enabled the instance will parse metadata from attached links to generate link previews",
children: [ children: [
%{ %{
key: :enabled, key: :enabled,
type: :boolean, type: :boolean,
description: "Enables RichMedia parsing of URLs." description: "Enables RichMedia parsing of URLs"
}, },
%{ %{
key: :ignore_hosts, key: :ignore_hosts,
type: {:list, :string}, type: {:list, :string},
description: "List of hosts which will be ignored by the metadata parser.", description: "List of hosts which will be ignored by the metadata parser",
suggestions: ["accounts.google.com", "xss.website"] suggestions: ["accounts.google.com", "xss.website"]
}, },
%{ %{
key: :ignore_tld, key: :ignore_tld,
label: "Ignore TLD", label: "Ignore TLD",
type: {:list, :string}, type: {:list, :string},
description: "List TLDs (top-level domains) which will ignore for parse metadata.", description: "List TLDs (top-level domains) which will ignore for parse metadata",
suggestions: ["local", "localdomain", "lan"] suggestions: ["local", "localdomain", "lan"]
}, },
%{ %{
@ -2159,31 +2223,32 @@
%{ %{
group: :auto_linker, group: :auto_linker,
key: :opts, key: :opts,
label: "Auto Linker",
type: :group, type: :group,
description: "Configuration for the auto_linker library", description: "Configuration for the auto_linker library",
children: [ children: [
%{ %{
key: :class, key: :class,
type: [:string, false], type: [:string, false],
description: "Specify the class to be added to the generated link. Disable 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. Disable to clear", description: "Override the rel attribute. Disable to clear.",
suggestions: ["ugc", "noopener noreferrer", false] suggestions: ["ugc", "noopener noreferrer", false]
}, },
%{ %{
key: :new_window, key: :new_window,
type: :boolean, type: :boolean,
description: "Link urls will open in new window/tab" description: "Link URLs will open in new window/tab"
}, },
%{ %{
key: :truncate, key: :truncate,
type: [:integer, false], type: [:integer, false],
description: description:
"Set to a number to truncate urls longer then the number. Truncated urls will end in `..`", "Set to a number to truncate URLs longer then the number. Truncated URLs will end in `..`",
suggestions: [15, false] suggestions: [15, false]
}, },
%{ %{
@ -2194,7 +2259,7 @@
%{ %{
key: :extra, key: :extra,
type: :boolean, type: :boolean,
description: "Link urls with rarely used schemes (magnet, ipfs, irc, etc.)" description: "Link URLs with rarely used schemes (magnet, ipfs, irc, etc.)"
} }
] ]
}, },
@ -2240,6 +2305,7 @@
}, },
%{ %{
group: :pleroma, group: :pleroma,
label: "Pleroma Authenticator",
type: :group, type: :group,
description: "Authenticator", description: "Authenticator",
children: [ children: [
@ -2253,6 +2319,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :ldap, key: :ldap,
label: "LDAP",
type: :group, type: :group,
description: description:
"Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password" <> "Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password" <>
@ -2339,6 +2406,7 @@
}, },
%{ %{
key: :uid, key: :uid,
label: "UID",
type: :string, type: :string,
description: description:
"LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"", "LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"",
@ -2354,6 +2422,7 @@
children: [ children: [
%{ %{
key: :enforce_oauth_admin_scope_usage, key: :enforce_oauth_admin_scope_usage,
label: "Enforce OAuth admin scope usage",
type: :boolean, type: :boolean,
description: description:
"OAuth admin scope requirement toggle. " <> "OAuth admin scope requirement toggle. " <>
@ -2370,6 +2439,7 @@
}, },
%{ %{
key: :oauth_consumer_template, key: :oauth_consumer_template,
label: "OAuth consumer template",
type: :string, type: :string,
description: description:
"OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to" <> "OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to" <>
@ -2378,6 +2448,7 @@
}, },
%{ %{
key: :oauth_consumer_strategies, key: :oauth_consumer_strategies,
label: "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." <>
@ -2506,7 +2577,7 @@
%{ %{
key: :enabled, key: :enabled,
type: :boolean, type: :boolean,
description: "enables new users admin digest email when `true`", description: "Enables new users admin digest email when `true`",
suggestions: [false] suggestions: [false]
} }
] ]
@ -2514,6 +2585,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :oauth2, key: :oauth2,
label: "OAuth2",
type: :group, type: :group,
description: "Configure OAuth 2 provider capabilities", description: "Configure OAuth 2 provider capabilities",
children: [ children: [
@ -2532,7 +2604,7 @@
%{ %{
key: :clean_expired_tokens, key: :clean_expired_tokens,
type: :boolean, type: :boolean,
description: "Enable a background job to clean expired oauth tokens. Default: disabled." description: "Enable a background job to clean expired OAuth tokens. Default: disabled."
} }
] ]
}, },
@ -2616,6 +2688,7 @@
}, },
%{ %{
key: :relation_id_action, key: :relation_id_action,
label: "Relation ID action",
type: [:tuple, {:list, :tuple}], type: [:tuple, {:list, :tuple}],
description: "For actions on relation with a specific user (follow, unfollow)", description: "For actions on relation with a specific user (follow, unfollow)",
suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]] suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
@ -2629,6 +2702,7 @@
}, },
%{ %{
key: :status_id_action, key: :status_id_action,
label: "Status ID action",
type: [:tuple, {:list, :tuple}], type: [:tuple, {:list, :tuple}],
description: description:
"For fav / unfav or reblog / unreblog actions on the same status by the same user", "For fav / unfav or reblog / unreblog actions on the same status by the same user",
@ -2644,6 +2718,7 @@
}, },
%{ %{
group: :esshd, group: :esshd,
label: "ESSHD",
type: :group, type: :group,
description: description:
"Before enabling this you must add :esshd to mix.exs as one of the extra_applications " <> "Before enabling this you must add :esshd to mix.exs as one of the extra_applications " <>
@ -2682,8 +2757,9 @@
}, },
%{ %{
group: :mime, group: :mime,
label: "Mime Types",
type: :group, type: :group,
description: "Mime types", description: "Mime Types settings",
children: [ children: [
%{ %{
key: :types, key: :types,
@ -2742,6 +2818,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :http, key: :http,
label: "HTTP",
type: :group, type: :group,
description: "HTTP settings", description: "HTTP settings",
children: [ children: [
@ -2790,6 +2867,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :markup, key: :markup,
label: "Markup Settings",
type: :group, type: :group,
children: [ children: [
%{ %{
@ -2830,8 +2908,9 @@
}, },
%{ %{
group: :pleroma, group: :pleroma,
tab: :mrf,
key: :mrf_normalize_markup, key: :mrf_normalize_markup,
label: "MRF normalize markup", label: "MRF Normalize Markup",
description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.", description: "MRF NormalizeMarkup settings. Scrub configured hypertext markup.",
type: :group, type: :group,
children: [ children: [
@ -2887,6 +2966,7 @@
}, },
%{ %{
group: :cors_plug, group: :cors_plug,
label: "CORS plug config",
type: :group, type: :group,
children: [ children: [
%{ %{
@ -2959,6 +3039,7 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :web_cache_ttl, key: :web_cache_ttl,
label: "Web cache TTL",
type: :group, type: :group,
description: description:
"The expiration time for the web responses cache. Values should be in milliseconds or `nil` to disable expiration.", "The expiration time for the web responses cache. Values should be in milliseconds or `nil` to disable expiration.",
@ -2981,9 +3062,10 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :static_fe, key: :static_fe,
label: "Static FE",
type: :group, type: :group,
description: description:
"Render profiles and posts using server-generated HTML that is viewable without using JavaScript.", "Render profiles and posts using server-generated HTML that is viewable without using JavaScript",
children: [ children: [
%{ %{
key: :enabled, key: :enabled,
@ -3001,18 +3083,18 @@
%{ %{
key: :post_title, key: :post_title,
type: :map, type: :map,
description: "Configure title rendering.", description: "Configure title rendering",
children: [ children: [
%{ %{
key: :max_length, key: :max_length,
type: :integer, type: :integer,
description: "Maximum number of characters before truncating title.", description: "Maximum number of characters before truncating title",
suggestions: [100] suggestions: [100]
}, },
%{ %{
key: :omission, key: :omission,
type: :string, type: :string,
description: "Replacement which will be used after truncating string.", description: "Replacement which will be used after truncating string",
suggestions: ["..."] suggestions: ["..."]
} }
] ]
@ -3022,8 +3104,11 @@
%{ %{
group: :pleroma, group: :pleroma,
key: :mrf_object_age, key: :mrf_object_age,
label: "MRF Object Age",
tab: :mrf,
type: :group, type: :group,
description: "Rejects or delists posts based on their age when received.", description:
"Rejects or delists posts based on their timestamp deviance from your server's clock.",
children: [ children: [
%{ %{
key: :threshold, key: :threshold,
@ -3036,7 +3121,7 @@
type: {:list, :atom}, type: {:list, :atom},
description: description:
"A list of actions to apply to the post. `:delist` removes the post from public timelines; " <> "A list of actions to apply to the post. `:delist` removes the post from public timelines; " <>
"`:strip_followers` removes followers from the ActivityPub recipient list, ensuring they won't be delivered to home timelines; " <> "`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <>
"`:reject` rejects the message entirely", "`:reject` rejects the message entirely",
suggestions: [:delist, :strip_followers, :reject] suggestions: [:delist, :strip_followers, :reject]
} }
@ -3064,13 +3149,13 @@
%{ %{
key: :workers, key: :workers,
type: :integer, type: :integer,
description: "Number of workers to send notifications.", description: "Number of workers to send notifications",
suggestions: [3] suggestions: [3]
}, },
%{ %{
key: :overflow_workers, key: :overflow_workers,
type: :integer, type: :integer,
description: "Maximum number of workers created if pool is empty.", description: "Maximum number of workers created if pool is empty",
suggestions: [2] suggestions: [2]
} }
] ]
@ -3361,41 +3446,5 @@
suggestions: [false] suggestions: [false]
} }
] ]
},
%{
group: :pleroma,
key: :mrf,
type: :group,
description: "General MRF settings",
children: [
%{
key: :policies,
type: [:module, {:list, :module}],
description:
"A list of MRF policies enabled. Module names are shortened (removed leading `Pleroma.Web.ActivityPub.MRF.` part), but on adding custom module you need to use full name.",
suggestions:
Generator.list_modules_in_dir(
"lib/pleroma/web/activity_pub/mrf",
"Elixir.Pleroma.Web.ActivityPub.MRF."
)
},
%{
key: :transparency,
label: "MRF transparency",
type: :boolean,
description:
"Make the content of your Message Rewrite Facility settings public (via nodeinfo)"
},
%{
key: :transparency_exclusions,
label: "MRF transparency exclusions",
type: {:list, :string},
description:
"Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.",
suggestions: [
"exclusion.com"
]
}
]
} }
] ]

View file

@ -228,6 +228,7 @@ Has theses additional parameters (which are the same as in Pleroma-API):
- `background_image`: A background image that frontends can use - `background_image`: A background image that frontends can use
- `pleroma.metadata.features`: A list of supported features - `pleroma.metadata.features`: A list of supported features
- `pleroma.metadata.federation`: The federation restrictions of this instance - `pleroma.metadata.federation`: The federation restrictions of this instance
- `pleroma.metadata.fields_limits`: A list of values detailing the length and count limitation for various instance-configurable fields.
- `vapid_public_key`: The public key needed for push messages - `vapid_public_key`: The public key needed for push messages
## Markers ## Markers

View file

@ -12,6 +12,11 @@ defmodule Pleroma.Config.Loader do
:swarm :swarm
] ]
@reject_groups [
:postgrex,
:tesla
]
if Code.ensure_loaded?(Config.Reader) do if Code.ensure_loaded?(Config.Reader) do
@reader Config.Reader @reader Config.Reader
@ -47,7 +52,8 @@ defp filter(configs) do
@spec filter_group(atom(), keyword()) :: keyword() @spec filter_group(atom(), keyword()) :: keyword()
def filter_group(group, configs) do def filter_group(group, configs) do
Enum.reject(configs[group], fn {key, _v} -> Enum.reject(configs[group], fn {key, _v} ->
key in @reject_keys or (group == :phoenix and key == :serve_endpoints) or group == :postgrex key in @reject_keys or group in @reject_groups or
(group == :phoenix and key == :serve_endpoints)
end) end)
end end
end end

View file

@ -109,7 +109,7 @@ def extract_first_external_url(object, content) do
result = result =
content content
|> Floki.parse_fragment!() |> Floki.parse_fragment!()
|> Floki.filter_out("a.mention,a.hashtag,a[rel~=\"tag\"]") |> Floki.filter_out("a.mention,a.hashtag,a.attachment,a[rel~=\"tag\"]")
|> Floki.attribute("a", "href") |> Floki.attribute("a", "href")
|> Enum.at(0) |> Enum.at(0)

View file

@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.MigrationHelper.NotificationBackfill do defmodule Pleroma.MigrationHelper.NotificationBackfill do
alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
@ -25,18 +24,27 @@ def fill_in_notification_types do
|> type_from_activity() |> type_from_activity()
notification notification
|> Notification.changeset(%{type: type}) |> Ecto.Changeset.change(%{type: type})
|> Repo.update() |> Repo.update()
end) end)
end end
defp get_by_ap_id(ap_id) do
q =
from(u in User,
select: u.id
)
Repo.get_by(q, ap_id: ap_id)
end
# This is copied over from Notifications to keep this stable. # This is copied over from Notifications to keep this stable.
defp type_from_activity(%{data: %{"type" => type}} = activity) do defp type_from_activity(%{data: %{"type" => type}} = activity) do
case type do case type do
"Follow" -> "Follow" ->
accepted_function = fn activity -> accepted_function = fn activity ->
with %User{} = follower <- User.get_by_ap_id(activity.data["actor"]), with %User{} = follower <- get_by_ap_id(activity.data["actor"]),
%User{} = followed <- User.get_by_ap_id(activity.data["object"]) do %User{} = followed <- get_by_ap_id(activity.data["object"]) do
Pleroma.FollowingRelationship.following?(follower, followed) Pleroma.FollowingRelationship.following?(follower, followed)
end end
end end

View file

@ -367,6 +367,7 @@ defp do_create_notifications(%Activity{} = activity, options) do
do_send = do_send && user in enabled_receivers do_send = do_send && user in enabled_receivers
create_notification(activity, user, do_send) create_notification(activity, user, do_send)
end) end)
|> Enum.reject(&is_nil/1)
{:ok, notifications} {:ok, notifications}
end end

View file

@ -115,7 +115,7 @@ defmodule Pleroma.User do
field(:is_moderator, :boolean, default: false) field(:is_moderator, :boolean, default: false)
field(:is_admin, :boolean, default: false) field(:is_admin, :boolean, default: false)
field(:show_role, :boolean, default: true) field(:show_role, :boolean, default: true)
field(:settings, :map, default: nil) field(:mastofe_settings, :map, default: nil)
field(:uri, ObjectValidators.Uri, default: nil) field(:uri, ObjectValidators.Uri, default: nil)
field(:hide_followers_count, :boolean, default: false) field(:hide_followers_count, :boolean, default: false)
field(:hide_follows_count, :boolean, default: false) field(:hide_follows_count, :boolean, default: false)
@ -2118,8 +2118,8 @@ def mascot_update(user, url) do
def mastodon_settings_update(user, settings) do def mastodon_settings_update(user, settings) do
user user
|> cast(%{settings: settings}, [:settings]) |> cast(%{mastofe_settings: settings}, [:mastofe_settings])
|> validate_required([:settings]) |> validate_required([:mastofe_settings])
|> update_and_set_cache() |> update_and_set_cache()
end end

View file

@ -52,6 +52,7 @@ defp search_query(query_string, for_user, following) do
|> base_query(following) |> base_query(following)
|> filter_blocked_user(for_user) |> filter_blocked_user(for_user)
|> filter_invisible_users() |> filter_invisible_users()
|> filter_internal_users()
|> filter_blocked_domains(for_user) |> filter_blocked_domains(for_user)
|> fts_search(query_string) |> fts_search(query_string)
|> trigram_rank(query_string) |> trigram_rank(query_string)
@ -109,6 +110,10 @@ defp filter_invisible_users(query) do
from(q in query, where: q.invisible == false) from(q in query, where: q.invisible == false)
end end
defp filter_internal_users(query) do
from(q in query, where: q.actor_type != "Application")
end
defp filter_blocked_user(query, %User{} = blocker) do defp filter_blocked_user(query, %User{} = blocker) do
query query
|> join(:left, [u], b in Pleroma.UserRelationship, |> join(:left, [u], b in Pleroma.UserRelationship,

View file

@ -1371,6 +1371,16 @@ def fetch_and_prepare_user_from_ap_id(ap_id) do
end end
end end
def maybe_handle_clashing_nickname(nickname) do
with %User{} = old_user <- User.get_by_nickname(nickname) do
Logger.info("Found an old user for #{nickname}, ap id is #{old_user.ap_id}, renaming.")
old_user
|> User.remote_user_changeset(%{nickname: "#{old_user.id}.#{old_user.nickname}"})
|> User.update_and_set_cache()
end
end
def make_user_from_ap_id(ap_id) do def make_user_from_ap_id(ap_id) do
user = User.get_cached_by_ap_id(ap_id) user = User.get_cached_by_ap_id(ap_id)
@ -1383,6 +1393,8 @@ def make_user_from_ap_id(ap_id) do
|> User.remote_user_changeset(data) |> User.remote_user_changeset(data)
|> User.update_and_set_cache() |> User.update_and_set_cache()
else else
maybe_handle_clashing_nickname(data[:nickname])
data data
|> User.remote_user_changeset() |> User.remote_user_changeset()
|> Repo.insert() |> Repo.insert()

View file

@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do
collection, and so on. collection, and so on.
""" """
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Activity.Ir.Topics
alias Pleroma.Chat alias Pleroma.Chat
alias Pleroma.Chat.MessageReference alias Pleroma.Chat.MessageReference
alias Pleroma.Notification alias Pleroma.Notification
@ -97,7 +98,10 @@ def handle(%{data: %{"type" => "Announce"}} = object, meta) do
if !User.is_internal_user?(user) do if !User.is_internal_user?(user) do
Notification.create_notifications(object) Notification.create_notifications(object)
ActivityPub.stream_out(object)
object
|> Topics.get_activity_topics()
|> Streamer.stream(object)
end end
{:ok, object, meta} {:ok, object, meta}

View file

@ -446,12 +446,9 @@ def handle_incoming(
when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer", "Audio"] do when objtype in ["Article", "Event", "Note", "Video", "Page", "Question", "Answer", "Audio"] do
actor = Containment.get_actor(data) actor = Containment.get_actor(data)
data =
Map.put(data, "actor", actor)
|> fix_addressing
with nil <- Activity.get_create_by_object_ap_id(object["id"]), with nil <- Activity.get_create_by_object_ap_id(object["id"]),
{:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(data["actor"]) do {:ok, %User{} = user} <- User.get_or_fetch_by_ap_id(actor),
data <- Map.put(data, "actor", actor) |> fix_addressing() do
object = fix_object(object, options) object = fix_object(object, options)
params = %{ params = %{

View file

@ -40,7 +40,7 @@ def call(%{private: %{open_api_spex: private_data}} = conn, %{
|> List.first() |> List.first()
_ -> _ ->
nil "application/json"
end end
private_data = Map.put(private_data, :operation_id, operation_id) private_data = Map.put(private_data, :operation_id, operation_id)

View file

@ -84,7 +84,7 @@ def delete_operation do
operationId: "StatusController.delete", operationId: "StatusController.delete",
parameters: [id_param()], parameters: [id_param()],
responses: %{ responses: %{
200 => empty_object_response(), 200 => status_response(),
403 => Operation.response("Forbidden", "application/json", ApiError), 403 => Operation.response("Forbidden", "application/json", ApiError),
404 => Operation.response("Not Found", "application/json", ApiError) 404 => Operation.response("Not Found", "application/json", ApiError)
} }

View file

@ -62,6 +62,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
} }
}, },
content: %Schema{type: :string, format: :html, description: "HTML-encoded status content"}, content: %Schema{type: :string, format: :html, description: "HTML-encoded status content"},
text: %Schema{
type: :string,
description: "Original unformatted content in plain text",
nullable: true
},
created_at: %Schema{ created_at: %Schema{
type: :string, type: :string,
format: "date-time", format: "date-time",

View file

@ -186,6 +186,7 @@ defp object(draft) do
draft.poll draft.poll
) )
|> Map.put("emoji", emoji) |> Map.put("emoji", emoji)
|> Map.put("source", draft.status)
%__MODULE__{draft | object: object} %__MODULE__{draft | object: object}
end end

View file

@ -44,6 +44,7 @@ def search2(conn, params), do: do_search(:v2, conn, params)
def search(conn, params), do: do_search(:v1, conn, params) def search(conn, params), do: do_search(:v1, conn, params)
defp do_search(version, %{assigns: %{user: user}} = conn, %{q: query} = params) do defp do_search(version, %{assigns: %{user: user}} = conn, %{q: query} = params) do
query = String.trim(query)
options = search_options(params, user) options = search_options(params, user)
timeout = Keyword.get(Repo.config(), :timeout, 15_000) timeout = Keyword.get(Repo.config(), :timeout, 15_000)
default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []} default_values = %{"statuses" => [], "accounts" => [], "hashtags" => []}

View file

@ -200,11 +200,18 @@ def show(%{assigns: %{user: user}} = conn, %{id: id}) do
@doc "DELETE /api/v1/statuses/:id" @doc "DELETE /api/v1/statuses/:id"
def delete(%{assigns: %{user: user}} = conn, %{id: id}) do def delete(%{assigns: %{user: user}} = conn, %{id: id}) do
with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do with %Activity{} = activity <- Activity.get_by_id_with_object(id),
json(conn, %{}) render <-
try_render(conn, "show.json",
activity: activity,
for: user,
with_direct_conversation_id: true,
with_source: true
),
{:ok, %Activity{}} <- CommonAPI.delete(id, user) do
render
else else
{:error, :not_found} = e -> e _e -> {:error, :not_found}
_e -> render_error(conn, :forbidden, "Can't delete this post")
end end
end end

View file

@ -36,8 +36,10 @@ def render("show.json", _) do
background_image: Keyword.get(instance, :background_image), background_image: Keyword.get(instance, :background_image),
pleroma: %{ pleroma: %{
metadata: %{ metadata: %{
account_activation_required: Keyword.get(instance, :account_activation_required),
features: features(), features: features(),
federation: federation() federation: federation(),
fields_limits: fields_limits()
}, },
vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key) vapid_public_key: Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key)
} }
@ -88,4 +90,13 @@ def federation do
end end
|> Map.put(:enabled, Config.get([:instance, :federating])) |> Map.put(:enabled, Config.get([:instance, :federating]))
end end
def fields_limits do
%{
max_fields: Config.get([:instance, :max_account_fields]),
max_remote_fields: Config.get([:instance, :max_remote_account_fields]),
name_length: Config.get([:instance, :account_field_name_length]),
value_length: Config.get([:instance, :account_field_value_length])
}
end
end end

View file

@ -333,6 +333,7 @@ def render("show.json", %{activity: %{data: %{"object" => _object}} = activity}
reblog: nil, reblog: nil,
card: card, card: card,
content: content_html, content: content_html,
text: opts[:with_source] && object.data["source"],
created_at: created_at, created_at: created_at,
reblogs_count: announcement_count, reblogs_count: announcement_count,
replies_count: object.data["repliesCount"] || 0, replies_count: object.data["repliesCount"] || 0,

View file

@ -3,14 +3,15 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.Instance do defmodule Pleroma.Web.Preload.Providers.Instance do
alias Pleroma.Plugs.InstanceStatic
alias Pleroma.Web.MastodonAPI.InstanceView alias Pleroma.Web.MastodonAPI.InstanceView
alias Pleroma.Web.Nodeinfo.Nodeinfo alias Pleroma.Web.Nodeinfo.Nodeinfo
alias Pleroma.Web.Preload.Providers.Provider alias Pleroma.Web.Preload.Providers.Provider
@behaviour Provider @behaviour Provider
@instance_url :"/api/v1/instance" @instance_url "/api/v1/instance"
@panel_url :"/instance/panel.html" @panel_url "/instance/panel.html"
@nodeinfo_url :"/nodeinfo/2.0" @nodeinfo_url "/nodeinfo/2.0.json"
@impl Provider @impl Provider
def generate_terms(_params) do def generate_terms(_params) do
@ -27,7 +28,7 @@ defp build_info_tag(acc) do
end end
defp build_panel_tag(acc) do defp build_panel_tag(acc) do
instance_path = Path.join(:code.priv_dir(:pleroma), "static/instance/panel.html") instance_path = InstanceStatic.file_path(@panel_url |> to_string())
if File.exists?(instance_path) do if File.exists?(instance_path) do
panel_data = File.read!(instance_path) panel_data = File.read!(instance_path)

View file

@ -4,10 +4,10 @@
defmodule Pleroma.Web.Preload.Providers.StatusNet do defmodule Pleroma.Web.Preload.Providers.StatusNet do
alias Pleroma.Web.Preload.Providers.Provider alias Pleroma.Web.Preload.Providers.Provider
alias Pleroma.Web.TwitterAPI.UtilView alias Pleroma.Web.TwitterAPI.UtilController
@behaviour Provider @behaviour Provider
@config_url :"/api/statusnet/config.json" @config_url "/api/statusnet/config.json"
@impl Provider @impl Provider
def generate_terms(_params) do def generate_terms(_params) do
@ -16,9 +16,10 @@ def generate_terms(_params) do
end end
defp build_config_tag(acc) do defp build_config_tag(acc) do
instance = Pleroma.Config.get(:instance) resp =
info_data = UtilView.status_net_config(instance) Plug.Test.conn(:get, @config_url |> to_string())
|> UtilController.config(nil)
Map.put(acc, @config_url, info_data) Map.put(acc, @config_url, resp.resp_body)
end end
end end

View file

@ -8,7 +8,7 @@ defmodule Pleroma.Web.Preload.Providers.Timelines do
alias Pleroma.Web.Preload.Providers.Provider alias Pleroma.Web.Preload.Providers.Provider
@behaviour Provider @behaviour Provider
@public_url :"/api/v1/timelines/public" @public_url "/api/v1/timelines/public"
@impl Provider @impl Provider
def generate_terms(params) do def generate_terms(params) do

View file

@ -3,11 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Preload.Providers.User do defmodule Pleroma.Web.Preload.Providers.User do
alias Pleroma.User
alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.Preload.Providers.Provider alias Pleroma.Web.Preload.Providers.Provider
@behaviour Provider @behaviour Provider
@account_url :"/api/v1/accounts" @account_url_base "/api/v1/accounts"
@impl Provider @impl Provider
def generate_terms(%{user: user}) do def generate_terms(%{user: user}) do
@ -16,10 +17,10 @@ def generate_terms(%{user: user}) do
def generate_terms(_params), do: %{} def generate_terms(_params), do: %{}
def build_accounts_tag(acc, nil), do: acc def build_accounts_tag(acc, %User{} = user) do
def build_accounts_tag(acc, user) do
account_data = AccountView.render("show.json", %{user: user, for: user}) account_data = AccountView.render("show.json", %{user: user, for: user})
Map.put(acc, @account_url, account_data) Map.put(acc, "#{@account_url_base}/#{user.id}", account_data)
end end
def build_accounts_tag(acc, _), do: acc
end end

View file

@ -104,7 +104,9 @@ def stream(topics, items) do
:ok :ok
end end
def filtered_by_user?(%User{} = user, %Activity{} = item) do def filtered_by_user?(user, item, streamed_type \\ :activity)
def filtered_by_user?(%User{} = user, %Activity{} = item, streamed_type) do
%{block: blocked_ap_ids, mute: muted_ap_ids, reblog_mute: reblog_muted_ap_ids} = %{block: blocked_ap_ids, mute: muted_ap_ids, reblog_mute: reblog_muted_ap_ids} =
User.outgoing_relationships_ap_ids(user, [:block, :mute, :reblog_mute]) User.outgoing_relationships_ap_ids(user, [:block, :mute, :reblog_mute])
@ -116,6 +118,9 @@ def filtered_by_user?(%User{} = user, %Activity{} = item) do
true <- true <-
Enum.all?([blocked_ap_ids, muted_ap_ids], &(item.actor not in &1)), Enum.all?([blocked_ap_ids, muted_ap_ids], &(item.actor not in &1)),
true <- item.data["type"] != "Announce" || item.actor not in reblog_muted_ap_ids, true <- item.data["type"] != "Announce" || item.actor not in reblog_muted_ap_ids,
true <-
!(streamed_type == :activity && item.data["type"] == "Announce" &&
parent.data["actor"] == user.ap_id),
true <- Enum.all?([blocked_ap_ids, muted_ap_ids], &(parent.data["actor"] not in &1)), true <- Enum.all?([blocked_ap_ids, muted_ap_ids], &(parent.data["actor"] not in &1)),
true <- MapSet.disjoint?(recipients, recipient_blocks), true <- MapSet.disjoint?(recipients, recipient_blocks),
%{host: item_host} <- URI.parse(item.actor), %{host: item_host} <- URI.parse(item.actor),
@ -130,8 +135,8 @@ def filtered_by_user?(%User{} = user, %Activity{} = item) do
end end
end end
def filtered_by_user?(%User{} = user, %Notification{activity: activity}) do def filtered_by_user?(%User{} = user, %Notification{activity: activity}, _) do
filtered_by_user?(user, activity) filtered_by_user?(user, activity, :notification)
end end
defp do_stream("direct", item) do defp do_stream("direct", item) do

View file

@ -86,7 +86,7 @@ def initial_state(token, user, custom_emojis) do
"video\/mp4" "video\/mp4"
] ]
}, },
settings: user.settings || @default_settings, settings: user.mastofe_settings || @default_settings,
push_subscription: nil, push_subscription: nil,
accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)}, accounts: %{user.id => render(AccountView, "show.json", user: user, for: user)},
custom_emojis: render(CustomEmojiView, "index.json", custom_emojis: custom_emojis), custom_emojis: render(CustomEmojiView, "index.json", custom_emojis: custom_emojis),

View file

@ -159,7 +159,10 @@ defp deps do
{:cors_plug, "~> 1.5"}, {:cors_plug, "~> 1.5"},
{:ex_doc, "~> 0.21", only: :dev, runtime: false}, {:ex_doc, "~> 0.21", only: :dev, runtime: false},
{:web_push_encryption, "~> 0.2.1"}, {:web_push_encryption, "~> 0.2.1"},
{:swoosh, "~> 0.23.2"}, {:swoosh,
git: "https://github.com/swoosh/swoosh",
ref: "c96e0ca8a00d8f211ec1f042a4626b09f249caa5",
override: true},
{: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},

View file

@ -104,9 +104,9 @@
"sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"}, "sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"}, "sweet_xml": {:hex, :sweet_xml, "0.6.6", "fc3e91ec5dd7c787b6195757fbcf0abc670cee1e4172687b45183032221b66b8", [:mix], [], "hexpm", "2e1ec458f892ffa81f9f8386e3f35a1af6db7a7a37748a64478f13163a1f3573"},
"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": {:git, "https://github.com/swoosh/swoosh", "c96e0ca8a00d8f211ec1f042a4626b09f249caa5", [ref: "c96e0ca8a00d8f211ec1f042a4626b09f249caa5"]},
"syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"}, "syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"},
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"}, "telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
"tesla": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/tesla.git", "61b7503cef33f00834f78ddfafe0d5d9dec2270b", [ref: "61b7503cef33f00834f78ddfafe0d5d9dec2270b"]}, "tesla": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/tesla.git", "61b7503cef33f00834f78ddfafe0d5d9dec2270b", [ref: "61b7503cef33f00834f78ddfafe0d5d9dec2270b"]},
"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", "f354efb2400dd7a80fd9eb6c8419068c4f632da4ac47f3d8822d6e33f08bc852"},
"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", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},

View file

@ -0,0 +1,11 @@
defmodule Pleroma.Repo.Migrations.RenameUserSettingsCol do
use Ecto.Migration
def up do
rename(table(:users), :settings, to: :mastofe_settings)
end
def down do
rename(table(:users), :mastofe_settings, to: :settings)
end
end

View file

@ -0,0 +1,10 @@
defmodule Pleroma.Repo.Migrations.RemoveTeslaFromConfig do
use Ecto.Migration
def up do
execute("DELETE FROM config WHERE config.group = ':tesla'")
end
def down do
end
end

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

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.686b5876.css rel=stylesheet><link href=app.6684eb28.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.5bae86dc.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.3fcec8f6.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.01bdb34a.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.0a70a9f5.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.f220ac13.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

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,2 +1,2 @@
!function(e){function n(n){for(var t,r,a=n[0],f=n[1],h=n[2],i=0,l=[];i<a.length;i++)r=a[i],u[r]&&l.push(u[r][0]),u[r]=0;for(t in f)Object.prototype.hasOwnProperty.call(f,t)&&(e[t]=f[t]);for(d&&d(n);l.length;)l.shift()();return o.push.apply(o,h||[]),c()}function c(){for(var e,n=0;n<o.length;n++){for(var c=o[n],t=!0,r=1;r<c.length;r++){var f=c[r];0!==u[f]&&(t=!1)}t&&(o.splice(n--,1),e=a(a.s=c[0]))}return e}var t={},r={runtime:0},u={runtime:0},o=[];function a(n){if(t[n])return t[n].exports;var c=t[n]={i:n,l:!1,exports:{}};return e[n].call(c.exports,c,c.exports,a),c.l=!0,c.exports}a.e=function(e){var n=[];r[e]?n.push(r[e]):0!==r[e]&&{"chunk-070d":1,"chunk-6e81":1,"chunk-commons":1,"chunk-143c":1,"chunk-0cbc":1,"chunk-43ca":1,"chunk-7c6b":1,"chunk-c5f4":1,"chunk-176e":1,"chunk-e404":1,"chunk-1609":1,"chunk-5882":1,"chunk-7506":1,"chunk-4e7e":1}[e]&&n.push(r[e]=new Promise(function(n,c){for(var t=({"chunk-commons":"chunk-commons"}[e]||e)+"."+{"7zzA":"31d6cfe0",JEtC:"31d6cfe0","chunk-070d":"d2dd6533","chunk-6e81":"ca3b222f","chunk-commons":"7f6d2d11",ZhIB:"31d6cfe0","chunk-143c":"43ada4fc","chunk-0cbc":"60bba79b","chunk-5118":"31d6cfe0","chunk-43ca":"0de86b6d","chunk-7c6b":"d9e7180a","chunk-c5f4":"0827b1ce","chunk-df62":"31d6cfe0","chunk-176e":"5d7d957b","chunk-e404":"a56021ae","chunk-1609":"408dae86","chunk-5882":"f65db7f2","chunk-7506":"f01f6c2a",oAJy:"31d6cfe0","chunk-16d0":"31d6cfe0","chunk-4e7e":"5afe1978"}[e]+".css",r=a.p+t,u=document.getElementsByTagName("link"),o=0;o<u.length;o++){var f=(i=u[o]).getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(f===t||f===r))return n()}var h=document.getElementsByTagName("style");for(o=0;o<h.length;o++){var i;if((f=(i=h[o]).getAttribute("data-href"))===t||f===r)return n()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=n,d.onerror=function(n){var t=n&&n.target&&n.target.src||r,u=new Error("Loading CSS chunk "+e+" failed.\n("+t+")");u.request=t,c(u)},d.href=r,document.getElementsByTagName("head")[0].appendChild(d)}).then(function(){r[e]=0}));var c=u[e];if(0!==c)if(c)n.push(c[2]);else{var t=new Promise(function(n,t){c=u[e]=[n,t]});n.push(c[2]=t);var o,f=document.createElement("script");f.charset="utf-8",f.timeout=120,a.nc&&f.setAttribute("nonce",a.nc),f.src=function(e){return a.p+"static/js/"+({"chunk-commons":"chunk-commons"}[e]||e)+"."+{"7zzA":"e1ae1c94",JEtC:"f9ba4594","chunk-070d":"7e10a520","chunk-6e81":"6efb01f4","chunk-commons":"5a106955",ZhIB:"861df339","chunk-143c":"fc1825bf","chunk-0cbc":"43ff796f","chunk-5118":"7c48ad58","chunk-43ca":"3debeff7","chunk-7c6b":"e63ae1da","chunk-c5f4":"304479e7","chunk-df62":"6c5105a6","chunk-176e":"c4995511","chunk-e404":"554bc2e3","chunk-1609":"98da6b01","chunk-5882":"7cbc4c1b","chunk-7506":"a3364e53",oAJy:"840fb1c2","chunk-16d0":"6ce78978","chunk-4e7e":"91b5e73a"}[e]+".js"}(e),o=function(n){f.onerror=f.onload=null,clearTimeout(h);var c=u[e];if(0!==c){if(c){var t=n&&("load"===n.type?"missing":n.type),r=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+t+": "+r+")");o.type=t,o.request=r,c[1](o)}u[e]=void 0}};var h=setTimeout(function(){o({type:"timeout",target:f})},12e4);f.onerror=f.onload=o,document.head.appendChild(f)}return Promise.all(n)},a.m=e,a.c=t,a.d=function(e,n,c){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:c})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var c=Object.create(null);if(a.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var t in e)a.d(c,t,function(n){return e[n]}.bind(null,t));return c},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="",a.oe=function(e){throw console.error(e),e};var f=window.webpackJsonp=window.webpackJsonp||[],h=f.push.bind(f);f.push=n,f=f.slice();for(var i=0;i<f.length;i++)n(f[i]);var d=h;c()}([]); !function(e){function n(n){for(var t,r,a=n[0],f=n[1],h=n[2],i=0,l=[];i<a.length;i++)r=a[i],u[r]&&l.push(u[r][0]),u[r]=0;for(t in f)Object.prototype.hasOwnProperty.call(f,t)&&(e[t]=f[t]);for(d&&d(n);l.length;)l.shift()();return o.push.apply(o,h||[]),c()}function c(){for(var e,n=0;n<o.length;n++){for(var c=o[n],t=!0,r=1;r<c.length;r++){var f=c[r];0!==u[f]&&(t=!1)}t&&(o.splice(n--,1),e=a(a.s=c[0]))}return e}var t={},r={runtime:0},u={runtime:0},o=[];function a(n){if(t[n])return t[n].exports;var c=t[n]={i:n,l:!1,exports:{}};return e[n].call(c.exports,c,c.exports,a),c.l=!0,c.exports}a.e=function(e){var n=[];r[e]?n.push(r[e]):0!==r[e]&&{"chunk-070d":1,"chunk-6e81":1,"chunk-commons":1,"chunk-143c":1,"chunk-0cbc":1,"chunk-43ca":1,"chunk-7c6b":1,"chunk-c5f4":1,"chunk-176e":1,"chunk-e404":1,"chunk-1609":1,"chunk-5882":1,"chunk-7506":1,"chunk-4e7e":1}[e]&&n.push(r[e]=new Promise(function(n,c){for(var t=({"chunk-commons":"chunk-commons"}[e]||e)+"."+{"7zzA":"31d6cfe0",JEtC:"31d6cfe0","chunk-070d":"d2dd6533","chunk-6e81":"ca3b222f","chunk-commons":"7f6d2d11",ZhIB:"31d6cfe0","chunk-143c":"43ada4fc","chunk-0cbc":"60bba79b","chunk-5118":"31d6cfe0","chunk-43ca":"af749c6c","chunk-7c6b":"d9e7180a","chunk-c5f4":"b1112f18","chunk-df62":"31d6cfe0","chunk-176e":"5d7d957b","chunk-e404":"a56021ae","chunk-1609":"408dae86","chunk-5882":"f65db7f2","chunk-7506":"f01f6c2a",oAJy:"31d6cfe0","chunk-16d0":"31d6cfe0","chunk-4e7e":"5afe1978"}[e]+".css",r=a.p+t,u=document.getElementsByTagName("link"),o=0;o<u.length;o++){var f=(i=u[o]).getAttribute("data-href")||i.getAttribute("href");if("stylesheet"===i.rel&&(f===t||f===r))return n()}var h=document.getElementsByTagName("style");for(o=0;o<h.length;o++){var i;if((f=(i=h[o]).getAttribute("data-href"))===t||f===r)return n()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=n,d.onerror=function(n){var t=n&&n.target&&n.target.src||r,u=new Error("Loading CSS chunk "+e+" failed.\n("+t+")");u.request=t,c(u)},d.href=r,document.getElementsByTagName("head")[0].appendChild(d)}).then(function(){r[e]=0}));var c=u[e];if(0!==c)if(c)n.push(c[2]);else{var t=new Promise(function(n,t){c=u[e]=[n,t]});n.push(c[2]=t);var o,f=document.createElement("script");f.charset="utf-8",f.timeout=120,a.nc&&f.setAttribute("nonce",a.nc),f.src=function(e){return a.p+"static/js/"+({"chunk-commons":"chunk-commons"}[e]||e)+"."+{"7zzA":"e1ae1c94",JEtC:"f9ba4594","chunk-070d":"7e10a520","chunk-6e81":"6efb01f4","chunk-commons":"5a106955",ZhIB:"861df339","chunk-143c":"fc1825bf","chunk-0cbc":"2b0f8802","chunk-5118":"7c48ad58","chunk-43ca":"aceb457c","chunk-7c6b":"e63ae1da","chunk-c5f4":"cf269f9b","chunk-df62":"6c5105a6","chunk-176e":"c4995511","chunk-e404":"554bc2e3","chunk-1609":"98da6b01","chunk-5882":"7cbc4c1b","chunk-7506":"a3364e53",oAJy:"840fb1c2","chunk-16d0":"6ce78978","chunk-4e7e":"91b5e73a"}[e]+".js"}(e),o=function(n){f.onerror=f.onload=null,clearTimeout(h);var c=u[e];if(0!==c){if(c){var t=n&&("load"===n.type?"missing":n.type),r=n&&n.target&&n.target.src,o=new Error("Loading chunk "+e+" failed.\n("+t+": "+r+")");o.type=t,o.request=r,c[1](o)}u[e]=void 0}};var h=setTimeout(function(){o({type:"timeout",target:f})},12e4);f.onerror=f.onload=o,document.head.appendChild(f)}return Promise.all(n)},a.m=e,a.c=t,a.d=function(e,n,c){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:c})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var c=Object.create(null);if(a.r(c),Object.defineProperty(c,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var t in e)a.d(c,t,function(n){return e[n]}.bind(null,t));return c},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="",a.oe=function(e){throw console.error(e),e};var f=window.webpackJsonp=window.webpackJsonp||[],h=f.push.bind(f);f.push=n,f=f.slice();for(var i=0;i<f.length;i++)n(f[i]);var d=h;c()}([]);
//# sourceMappingURL=runtime.5bae86dc.js.map //# sourceMappingURL=runtime.0a70a9f5.js.map

View file

@ -10,7 +10,6 @@ defmodule Pleroma.Config.HolderTest do
test "default_config/0" do test "default_config/0" do
config = Holder.default_config() config = Holder.default_config()
assert config[:pleroma][Pleroma.Uploaders.Local][:uploads] == "test/uploads" assert config[:pleroma][Pleroma.Uploaders.Local][:uploads] == "test/uploads"
assert config[:tesla][:adapter] == Tesla.Mock
refute config[:pleroma][Pleroma.Repo] refute config[:pleroma][Pleroma.Repo]
refute config[:pleroma][Pleroma.Web.Endpoint] refute config[:pleroma][Pleroma.Web.Endpoint]
@ -18,17 +17,15 @@ test "default_config/0" do
refute config[:pleroma][:configurable_from_database] refute config[:pleroma][:configurable_from_database]
refute config[:pleroma][:database] refute config[:pleroma][:database]
refute config[:phoenix][:serve_endpoints] refute config[:phoenix][:serve_endpoints]
refute config[:tesla][:adapter]
end end
test "default_config/1" do test "default_config/1" do
pleroma_config = Holder.default_config(:pleroma) pleroma_config = Holder.default_config(:pleroma)
assert pleroma_config[Pleroma.Uploaders.Local][:uploads] == "test/uploads" assert pleroma_config[Pleroma.Uploaders.Local][:uploads] == "test/uploads"
tesla_config = Holder.default_config(:tesla)
assert tesla_config[:adapter] == Tesla.Mock
end end
test "default_config/2" do test "default_config/2" do
assert Holder.default_config(:pleroma, Pleroma.Uploaders.Local) == [uploads: "test/uploads"] assert Holder.default_config(:pleroma, Pleroma.Uploaders.Local) == [uploads: "test/uploads"]
assert Holder.default_config(:tesla, :adapter) == Tesla.Mock
end end
end end

View file

@ -0,0 +1,72 @@
{
"@context" : [
"https://www.w3.org/ns/activitystreams",
{
"atomUri" : "ostatus:atomUri",
"conversation" : "ostatus:conversation",
"inReplyToAtomUri" : "ostatus:inReplyToAtomUri",
"ostatus" : "http://ostatus.org#",
"sensitive" : "as:sensitive",
"toot" : "http://joinmastodon.org/ns#",
"votersCount" : "toot:votersCount"
}
],
"atomUri" : "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069",
"attachment" : [],
"attributedTo" : "https://busshi.moe/users/tuxcrafting",
"cc" : [
"https://busshi.moe/users/tuxcrafting/followers",
"https://stereophonic.space/users/fixpoint",
"https://blob.cat/users/blobyoumu",
"https://cawfee.club/users/grips",
"https://jaeger.website/users/igel"
],
"content" : "<p><span class=\"h-card\"><a href=\"https://stereophonic.space/users/fixpoint\" class=\"u-url mention\">@<span>fixpoint</span></a></span> <span class=\"h-card\"><a href=\"https://blob.cat/users/blobyoumu\" class=\"u-url mention\">@<span>blobyoumu</span></a></span> <span class=\"h-card\"><a href=\"https://cawfee.club/users/grips\" class=\"u-url mention\">@<span>grips</span></a></span> <span class=\"h-card\"><a href=\"https://jaeger.website/users/igel\" class=\"u-url mention\">@<span>igel</span></a></span> there&apos;s a difference between not liking nukes and not liking nuclear power<br />nukes are pretty bad as are all WMDs in general but disliking nuclear power just indicates you are unable of thought</p>",
"contentMap" : {
"en" : "<p><span class=\"h-card\"><a href=\"https://stereophonic.space/users/fixpoint\" class=\"u-url mention\">@<span>fixpoint</span></a></span> <span class=\"h-card\"><a href=\"https://blob.cat/users/blobyoumu\" class=\"u-url mention\">@<span>blobyoumu</span></a></span> <span class=\"h-card\"><a href=\"https://cawfee.club/users/grips\" class=\"u-url mention\">@<span>grips</span></a></span> <span class=\"h-card\"><a href=\"https://jaeger.website/users/igel\" class=\"u-url mention\">@<span>igel</span></a></span> there&apos;s a difference between not liking nukes and not liking nuclear power<br />nukes are pretty bad as are all WMDs in general but disliking nuclear power just indicates you are unable of thought</p>"
},
"conversation" : "https://cawfee.club/contexts/ad6c73d8-efc2-4e74-84ea-2dacf1a27a5e",
"id" : "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069",
"inReplyTo" : "https://stereophonic.space/objects/02997b83-3ea7-4b63-94af-ef3aa2d4ed17",
"inReplyToAtomUri" : "https://stereophonic.space/objects/02997b83-3ea7-4b63-94af-ef3aa2d4ed17",
"published" : "2020-06-26T15:10:19Z",
"replies" : {
"first" : {
"items" : [],
"next" : "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069/replies?only_other_accounts=true&page=true",
"partOf" : "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069/replies",
"type" : "CollectionPage"
},
"id" : "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069/replies",
"type" : "Collection"
},
"sensitive" : false,
"summary" : null,
"tag" : [
{
"href" : "https://stereophonic.space/users/fixpoint",
"name" : "@fixpoint@stereophonic.space",
"type" : "Mention"
},
{
"href" : "https://blob.cat/users/blobyoumu",
"name" : "@blobyoumu@blob.cat",
"type" : "Mention"
},
{
"href" : "https://cawfee.club/users/grips",
"name" : "@grips@cawfee.club",
"type" : "Mention"
},
{
"href" : "https://jaeger.website/users/igel",
"name" : "@igel@jaeger.website",
"type" : "Mention"
}
],
"to" : [
"https://www.w3.org/ns/activitystreams#Public"
],
"type" : "Note",
"url" : "https://busshi.moe/@tuxcrafting/104410921027210069"
}

View file

@ -0,0 +1,59 @@
{
"@context" : [
"https://www.w3.org/ns/activitystreams",
"https://social.sakamoto.gq/schemas/litepub-0.1.jsonld",
{
"@language" : "und"
}
],
"actor" : "https://social.sakamoto.gq/users/eal",
"attachment" : [],
"attributedTo" : "https://social.sakamoto.gq/users/eal",
"cc" : [
"https://social.sakamoto.gq/users/eal/followers"
],
"content" : "<span class=\"h-card\"><a data-user=\"9uw2wH0iTYAMV7XnLU\" class=\"u-url mention\" href=\"https://busshi.moe/@tuxcrafting\" rel=\"ugc\">@<span>tuxcrafting</span></a></span> <span class=\"h-card\"><a data-user=\"9r5l8j8x23NI9KUFu4\" class=\"u-url mention\" href=\"https://stereophonic.space/users/fixpoint\" rel=\"ugc\">@<span>fixpoint</span></a></span> <span class=\"h-card\"><a data-user=\"9orDK545JwjY4Lxjge\" class=\"u-url mention\" href=\"https://blob.cat/users/blobyoumu\" rel=\"ugc\">@<span>blobyoumu</span></a></span> <span class=\"h-card\"><a data-user=\"68184\" class=\"u-url mention\" href=\"https://cawfee.club/users/grips\" rel=\"ugc\">@<span>grips</span></a></span> <span class=\"h-card\"><a data-user=\"9sAmMgHVKjTXKpgx84\" class=\"u-url mention\" href=\"https://jaeger.website/users/igel\" rel=\"ugc\">@<span>igel</span></a></span> What&#39;s bad about nukes?",
"context" : "https://cawfee.club/contexts/ad6c73d8-efc2-4e74-84ea-2dacf1a27a5e",
"conversation" : "https://cawfee.club/contexts/ad6c73d8-efc2-4e74-84ea-2dacf1a27a5e",
"id" : "https://social.sakamoto.gq/objects/f20f2497-66d9-4a52-a2e1-1be2a39c32c1",
"inReplyTo" : "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069",
"published" : "2020-06-26T15:20:15.975737Z",
"sensitive" : false,
"summary" : "",
"tag" : [
{
"href" : "https://blob.cat/users/blobyoumu",
"name" : "@blobyoumu@blob.cat",
"type" : "Mention"
},
{
"href" : "https://busshi.moe/users/tuxcrafting",
"name" : "@tuxcrafting@busshi.moe",
"type" : "Mention"
},
{
"href" : "https://cawfee.club/users/grips",
"name" : "@grips@cawfee.club",
"type" : "Mention"
},
{
"href" : "https://jaeger.website/users/igel",
"name" : "@igel@jaeger.website",
"type" : "Mention"
},
{
"href" : "https://stereophonic.space/users/fixpoint",
"name" : "@fixpoint@stereophonic.space",
"type" : "Mention"
}
],
"to" : [
"https://busshi.moe/users/tuxcrafting",
"https://www.w3.org/ns/activitystreams#Public",
"https://blob.cat/users/blobyoumu",
"https://stereophonic.space/users/fixpoint",
"https://cawfee.club/users/grips",
"https://jaeger.website/users/igel"
],
"type" : "Note"
}

43
test/fixtures/fetch_mocks/eal.json vendored Normal file
View file

@ -0,0 +1,43 @@
{
"@context" : [
"https://www.w3.org/ns/activitystreams",
"https://social.sakamoto.gq/schemas/litepub-0.1.jsonld",
{
"@language" : "und"
}
],
"attachment" : [],
"discoverable" : true,
"endpoints" : {
"oauthAuthorizationEndpoint" : "https://social.sakamoto.gq/oauth/authorize",
"oauthRegistrationEndpoint" : "https://social.sakamoto.gq/api/v1/apps",
"oauthTokenEndpoint" : "https://social.sakamoto.gq/oauth/token",
"sharedInbox" : "https://social.sakamoto.gq/inbox",
"uploadMedia" : "https://social.sakamoto.gq/api/ap/upload_media"
},
"followers" : "https://social.sakamoto.gq/users/eal/followers",
"following" : "https://social.sakamoto.gq/users/eal/following",
"icon" : {
"type" : "Image",
"url" : "https://social.sakamoto.gq/media/f1cb6f79bf6839f3223ca240441f766056b74ddd23c69bcaf8bb1ba1ecff6eec.jpg"
},
"id" : "https://social.sakamoto.gq/users/eal",
"image" : {
"type" : "Image",
"url" : "https://social.sakamoto.gq/media/e5cccf26421e8366f4e34be3c9d5042b8bc8dcceccc7c8e89785fa312dd9632c.jpg"
},
"inbox" : "https://social.sakamoto.gq/users/eal/inbox",
"manuallyApprovesFollowers" : false,
"name" : "에알",
"outbox" : "https://social.sakamoto.gq/users/eal/outbox",
"preferredUsername" : "eal",
"publicKey" : {
"id" : "https://social.sakamoto.gq/users/eal#main-key",
"owner" : "https://social.sakamoto.gq/users/eal",
"publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz3pF85YOhhv2Zaxv9YQ7\nrCe1aEhetCMVHtrK63tUVGoGdsblyKnVeJNbFcr6k3y35OpHS3HXIi6GzgihYcTu\nONLP4eQMHTnLUNAQZi03mjJA4iIq8v/tm8ZkL2mXsQSAbWj6Iq518mHNN7OvCoNt\n3Xjepl/0kgkc2gsund7m8r+Wu0Fusx6UlUyyAk3PexdDRdSSlVLeskqtP8jtdQDo\nL70pMyL+VD+Qb9RKFdtgJ+M4OqYP+7FVzCqXN0QIPhFf/kvHSLr+c4Y3Wm0nAKHU\n9CwXWXz5Xqscpv41KlgnUCOkTXb5eBSt23lNulae5srVzWBiFb6guiCpNzBGa+Sq\nrwIDAQAB\n-----END PUBLIC KEY-----\n\n"
},
"summary" : "Pizza napoletana supremacist.<br><br>Any artworks posted here that are good are not mine.",
"tag" : [],
"type" : "Person",
"url" : "https://social.sakamoto.gq/users/eal"
}

View file

@ -0,0 +1,59 @@
{
"@context" : [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"IdentityProof" : "toot:IdentityProof",
"PropertyValue" : "schema:PropertyValue",
"alsoKnownAs" : {
"@id" : "as:alsoKnownAs",
"@type" : "@id"
},
"discoverable" : "toot:discoverable",
"featured" : {
"@id" : "toot:featured",
"@type" : "@id"
},
"focalPoint" : {
"@container" : "@list",
"@id" : "toot:focalPoint"
},
"manuallyApprovesFollowers" : "as:manuallyApprovesFollowers",
"movedTo" : {
"@id" : "as:movedTo",
"@type" : "@id"
},
"schema" : "http://schema.org#",
"toot" : "http://joinmastodon.org/ns#",
"value" : "schema:value"
}
],
"attachment" : [],
"discoverable" : true,
"endpoints" : {
"sharedInbox" : "https://busshi.moe/inbox"
},
"featured" : "https://busshi.moe/users/tuxcrafting/collections/featured",
"followers" : "https://busshi.moe/users/tuxcrafting/followers",
"following" : "https://busshi.moe/users/tuxcrafting/following",
"icon" : {
"mediaType" : "image/jpeg",
"type" : "Image",
"url" : "https://blobcdn.busshi.moe/busshifiles/accounts/avatars/000/046/872/original/054f0806ccb303d0.jpg"
},
"id" : "https://busshi.moe/users/tuxcrafting",
"inbox" : "https://busshi.moe/users/tuxcrafting/inbox",
"manuallyApprovesFollowers" : true,
"name" : "@tuxcrafting@localhost:8080",
"outbox" : "https://busshi.moe/users/tuxcrafting/outbox",
"preferredUsername" : "tuxcrafting",
"publicKey" : {
"id" : "https://busshi.moe/users/tuxcrafting#main-key",
"owner" : "https://busshi.moe/users/tuxcrafting",
"publicKeyPem" : "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqWWTBf9OizsBiBhGS/M\nQTT6fB1VvQP6vvxouGZ5cGg1a97V67ouhjJ+nGMuWr++DNYjJYkk2TOynfykk0H/\n8rRSujSe3BNRKYGNzdnRJu/4XxgIE847Fqx5SijSP23JGYcn8TjeSUsN2u2YYVXK\n+Eb3Bu7DjGiqwNon6YB0h5qkGjkMSMVIFn0hZx6Z21bkfYWgra96Ok5OWf7Ck3je\nCuErlCMZcbQcHtFpBueJAxYchjNvm6fqwZxLX/NtaHdr7Fm2kin89mqzliapBlFH\nCXk7Jln6xV5I6ryggPAMzm3fuHzeo0RWlu8lrxLfARBVwaQQZS99bwqp6N9O2aUp\nYwIDAQAB\n-----END PUBLIC KEY-----\n"
},
"summary" : "<p>expert procrastinator</p><p>trans(humanist|gender|istorized)</p><p>web: <a href=\"https://tuxcrafting.port0.org\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">tuxcrafting.port0.org</span><span class=\"invisible\"></span></a><br />pronouns: she/they<br />languages: french (native)/english (fluent)/hebrew (ok-ish)/esperanto (barely)</p>",
"tag" : [],
"type" : "Person",
"url" : "https://busshi.moe/@tuxcrafting"
}

View file

@ -0,0 +1 @@
HEY!

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -237,5 +237,19 @@ test "does not crash when there is an HTML entity in a link" do
assert {:ok, nil} = HTML.extract_first_external_url(object, object.data["content"]) assert {:ok, nil} = HTML.extract_first_external_url(object, object.data["content"])
end end
test "skips attachment links" do
user = insert(:user)
{:ok, activity} =
CommonAPI.post(user, %{
status:
"<a href=\"https://pleroma.gov/media/d24caa3a498e21e0298377a9ca0149a4f4f8b767178aacf837542282e2d94fb1.png?name=image.png\" class=\"attachment\">image.png</a>"
})
object = Object.normalize(activity)
assert {:ok, nil} = HTML.extract_first_external_url(object, object.data["content"])
end
end end
end end

View file

@ -22,6 +22,16 @@ defmodule Pleroma.NotificationTest do
alias Pleroma.Web.Streamer alias Pleroma.Web.Streamer
describe "create_notifications" do describe "create_notifications" do
test "never returns nil" do
user = insert(:user)
other_user = insert(:user, %{invisible: true})
{:ok, activity} = CommonAPI.post(user, %{status: "yeah"})
{:ok, activity} = CommonAPI.react_with_emoji(activity.id, other_user, "")
refute {:ok, [nil]} == Notification.create_notifications(activity)
end
test "creates a notification for an emoji reaction" do test "creates a notification for an emoji reaction" do
user = insert(:user) user = insert(:user)
other_user = insert(:user) other_user = insert(:user)

View file

@ -26,6 +26,46 @@ defmodule Pleroma.Object.FetcherTest do
:ok :ok
end end
describe "error cases" do
setup do
mock(fn
%{method: :get, url: "https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/fetch_mocks/9wTkLEnuq47B25EehM.json")
}
%{method: :get, url: "https://social.sakamoto.gq/users/eal"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/fetch_mocks/eal.json")
}
%{method: :get, url: "https://busshi.moe/users/tuxcrafting/statuses/104410921027210069"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/fetch_mocks/104410921027210069.json")
}
%{method: :get, url: "https://busshi.moe/users/tuxcrafting"} ->
%Tesla.Env{
status: 500
}
end)
:ok
end
@tag capture_log: true
test "it works when fetching the OP actor errors out" do
# Here we simulate a case where the author of the OP can't be read
assert {:ok, _} =
Fetcher.fetch_object_from_id(
"https://social.sakamoto.gq/notice/9wTkLEnuq47B25EehM"
)
end
end
describe "max thread distance restriction" do describe "max thread distance restriction" do
@ap_id "http://mastodon.example.org/@admin/99541947525187367" @ap_id "http://mastodon.example.org/@admin/99541947525187367"
setup do: clear_config([:instance, :federation_incoming_replies_max_depth]) setup do: clear_config([:instance, :federation_incoming_replies_max_depth])

View file

@ -67,6 +67,7 @@ def note_factory(attrs \\ %{}) do
data = %{ data = %{
"type" => "Note", "type" => "Note",
"content" => text, "content" => text,
"source" => text,
"id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(), "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
"actor" => user.ap_id, "actor" => user.ap_id,
"to" => ["https://www.w3.org/ns/activitystreams#Public"], "to" => ["https://www.w3.org/ns/activitystreams#Public"],

View file

@ -17,7 +17,7 @@ defmodule Pleroma.UserSearchTest do
describe "User.search" do describe "User.search" do
setup do: clear_config([:instance, :limit_to_local_content]) setup do: clear_config([:instance, :limit_to_local_content])
test "excluded invisible users from results" do test "excludes invisible users from results" do
user = insert(:user, %{nickname: "john t1000"}) user = insert(:user, %{nickname: "john t1000"})
insert(:user, %{invisible: true, nickname: "john t800"}) insert(:user, %{invisible: true, nickname: "john t800"})
@ -25,6 +25,15 @@ test "excluded invisible users from results" do
assert found_user.id == user.id assert found_user.id == user.id
end end
test "excludes service actors from results" do
insert(:user, actor_type: "Application", nickname: "user1")
service = insert(:user, actor_type: "Service", nickname: "user2")
person = insert(:user, actor_type: "Person", nickname: "user3")
assert [found_user1, found_user2] = User.search("user")
assert [found_user1.id, found_user2.id] -- [service.id, person.id] == []
end
test "accepts limit parameter" do test "accepts limit parameter" do
Enum.each(0..4, &insert(:user, %{nickname: "john#{&1}"})) Enum.each(0..4, &insert(:user, %{nickname: "john#{&1}"}))
assert length(User.search("john", limit: 3)) == 3 assert length(User.search("john", limit: 3)) == 3

View file

@ -597,6 +597,31 @@ test "updates an existing user, if stale" do
refute user.last_refreshed_at == orig_user.last_refreshed_at refute user.last_refreshed_at == orig_user.last_refreshed_at
end end
test "if nicknames clash, the old user gets a prefix with the old id to the nickname" do
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
orig_user =
insert(
:user,
local: false,
nickname: "admin@mastodon.example.org",
ap_id: "http://mastodon.example.org/users/harinezumigari",
last_refreshed_at: a_week_ago
)
assert orig_user.last_refreshed_at == a_week_ago
{:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
assert user.inbox
refute user.id == orig_user.id
orig_user = User.get_by_id(orig_user.id)
assert orig_user.nickname == "#{orig_user.id}.admin@mastodon.example.org"
end
@tag capture_log: true @tag capture_log: true
test "it returns the old user if stale, but unfetchable" do test "it returns the old user if stale, but unfetchable" do
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800) a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)

View file

@ -589,10 +589,29 @@ test "creates a notification", %{announce: announce, poster: poster} do
end end
test "it streams out the announce", %{announce: announce} do test "it streams out the announce", %{announce: announce} do
with_mock Pleroma.Web.ActivityPub.ActivityPub, [:passthrough], stream_out: fn _ -> nil end do with_mocks([
{
Pleroma.Web.Streamer,
[],
[
stream: fn _, _ -> nil end
]
},
{
Pleroma.Web.Push,
[],
[
send: fn _ -> nil end
]
}
]) do
{:ok, announce, _} = SideEffects.handle(announce) {:ok, announce, _} = SideEffects.handle(announce)
assert called(Pleroma.Web.ActivityPub.ActivityPub.stream_out(announce)) assert called(
Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], announce)
)
assert called(Pleroma.Web.Push.send(:_))
end end
end end
end end

View file

@ -491,6 +491,7 @@ test "it filters out obviously bad tags when accepting a post as HTML" do
object = Object.normalize(activity) object = Object.normalize(activity)
assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)" assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
assert object.data["source"] == post
end end
test "it filters out obviously bad tags when accepting a post as Markdown" do test "it filters out obviously bad tags when accepting a post as Markdown" do
@ -507,6 +508,7 @@ test "it filters out obviously bad tags when accepting a post as Markdown" do
object = Object.normalize(activity) object = Object.normalize(activity)
assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)" assert object.data["content"] == "<p><b>2hu</b></p>alert(&#39;xss&#39;)"
assert object.data["source"] == post
end end
test "it does not allow replies to direct messages that are not direct messages themselves" do test "it does not allow replies to direct messages that are not direct messages themselves" do

View file

@ -24,7 +24,7 @@ test "put settings", %{conn: conn} do
assert _result = json_response(conn, 200) assert _result = json_response(conn, 200)
user = User.get_cached_by_ap_id(user.ap_id) user = User.get_cached_by_ap_id(user.ap_id)
assert user.settings == %{"programming" => "socks"} assert user.mastofe_settings == %{"programming" => "socks"}
end end
describe "index/2 redirections" do describe "index/2 redirections" do

View file

@ -216,20 +216,10 @@ test "updates the user's avatar", %{user: user, conn: conn} do
filename: "an_image.jpg" filename: "an_image.jpg"
} }
res = conn = patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
conn
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar})
assert user_response = json_response_and_validate_schema(res, 200) assert user_response = json_response_and_validate_schema(conn, 200)
assert user_response["avatar"] != User.avatar_url(user) assert user_response["avatar"] != User.avatar_url(user)
# Also removes it
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{"avatar" => nil})
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["avatar"] == User.avatar_url(user)
end end
test "updates the user's banner", %{user: user, conn: conn} do test "updates the user's banner", %{user: user, conn: conn} do
@ -239,21 +229,10 @@ test "updates the user's banner", %{user: user, conn: conn} do
filename: "an_image.jpg" filename: "an_image.jpg"
} }
res = conn = patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header})
conn
|> patch("/api/v1/accounts/update_credentials", %{"header" => new_header})
assert user_response = json_response_and_validate_schema(res, 200) assert user_response = json_response_and_validate_schema(conn, 200)
assert user_response["header"] != User.banner_url(user) assert user_response["header"] != User.banner_url(user)
# Also removes it
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{"header" => nil})
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["header"] == User.banner_url(user)
end end
test "updates the user's background", %{conn: conn} do test "updates the user's background", %{conn: conn} do
@ -263,25 +242,13 @@ test "updates the user's background", %{conn: conn} do
filename: "an_image.jpg" filename: "an_image.jpg"
} }
res = conn =
conn patch(conn, "/api/v1/accounts/update_credentials", %{
|> patch("/api/v1/accounts/update_credentials", %{
"pleroma_background_image" => new_header "pleroma_background_image" => new_header
}) })
assert user_response = json_response_and_validate_schema(res, 200) assert user_response = json_response_and_validate_schema(conn, 200)
assert user_response["pleroma"]["background_image"] assert user_response["pleroma"]["background_image"]
# Also removes it
res =
conn
|> patch("/api/v1/accounts/update_credentials", %{
"pleroma_background_image" => nil
})
assert user_response = json_response_and_validate_schema(res, 200)
refute user_response["pleroma"]["background_image"]
end end
test "requires 'write:accounts' permission" do test "requires 'write:accounts' permission" do

View file

@ -780,7 +780,6 @@ test "with notifications", %{conn: conn} do
assert %{"id" => _id, "muting" => true, "muting_notifications" => true} = assert %{"id" => _id, "muting" => true, "muting_notifications" => true} =
conn conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/accounts/#{other_user.id}/mute") |> post("/api/v1/accounts/#{other_user.id}/mute")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)

View file

@ -35,8 +35,10 @@ test "get instance information", %{conn: conn} do
"background_image" => _ "background_image" => _
} = result } = result
assert result["pleroma"]["metadata"]["account_activation_required"] != nil
assert result["pleroma"]["metadata"]["features"] assert result["pleroma"]["metadata"]["features"]
assert result["pleroma"]["metadata"]["federation"] assert result["pleroma"]["metadata"]["federation"]
assert result["pleroma"]["metadata"]["fields_limits"]
assert result["pleroma"]["vapid_public_key"] assert result["pleroma"]["vapid_public_key"]
assert email == from_config_email assert email == from_config_email

View file

@ -79,6 +79,7 @@ test "search", %{conn: conn} do
assert status["id"] == to_string(activity.id) assert status["id"] == to_string(activity.id)
end end
@tag capture_log: true
test "constructs hashtags from search query", %{conn: conn} do test "constructs hashtags from search query", %{conn: conn} do
results = results =
conn conn
@ -318,11 +319,13 @@ test "search doesn't show statuses that it shouldn't", %{conn: conn} do
test "search fetches remote accounts", %{conn: conn} do test "search fetches remote accounts", %{conn: conn} do
user = insert(:user) user = insert(:user)
query = URI.encode_query(%{q: " mike@osada.macgirvin.com ", resolve: true})
results = results =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> assign(:token, insert(:oauth_token, user: user, scopes: ["read"])) |> assign(:token, insert(:oauth_token, user: user, scopes: ["read"]))
|> get("/api/v1/search?q=mike@osada.macgirvin.com&resolve=true") |> get("/api/v1/search?#{query}")
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
[account] = results["accounts"] [account] = results["accounts"]

View file

@ -760,13 +760,18 @@ test "if user is authenticated", %{local: local, remote: remote} do
test "when you created it" do test "when you created it" do
%{user: author, conn: conn} = oauth_access(["write:statuses"]) %{user: author, conn: conn} = oauth_access(["write:statuses"])
activity = insert(:note_activity, user: author) activity = insert(:note_activity, user: author)
object = Object.normalize(activity)
conn = content = object.data["content"]
source = object.data["source"]
result =
conn conn
|> assign(:user, author) |> assign(:user, author)
|> delete("/api/v1/statuses/#{activity.id}") |> delete("/api/v1/statuses/#{activity.id}")
|> json_response_and_validate_schema(200)
assert %{} = json_response_and_validate_schema(conn, 200) assert match?(%{"content" => ^content, "text" => ^source}, result)
refute Activity.get_by_id(activity.id) refute Activity.get_by_id(activity.id)
end end
@ -789,7 +794,7 @@ test "when you didn't create it" do
conn = delete(conn, "/api/v1/statuses/#{activity.id}") conn = delete(conn, "/api/v1/statuses/#{activity.id}")
assert %{"error" => _} = json_response_and_validate_schema(conn, 403) assert %{"error" => "Record not found"} == json_response_and_validate_schema(conn, 404)
assert Activity.get_by_id(activity.id) == activity assert Activity.get_by_id(activity.id) == activity
end end

View file

@ -183,6 +183,7 @@ test "a note activity" do
card: nil, card: nil,
reblog: nil, reblog: nil,
content: HTML.filter_tags(object_data["content"]), content: HTML.filter_tags(object_data["content"]),
text: nil,
created_at: created_at, created_at: created_at,
reblogs_count: 0, reblogs_count: 0,
replies_count: 0, replies_count: 0,

View file

@ -8,7 +8,7 @@ defmodule Pleroma.Web.Preload.Providers.InstanceTest do
setup do: {:ok, Instance.generate_terms(nil)} setup do: {:ok, Instance.generate_terms(nil)}
test "it renders the info", %{"/api/v1/instance": info} do test "it renders the info", %{"/api/v1/instance" => info} do
assert %{ assert %{
description: description, description: description,
email: "admin@example.com", email: "admin@example.com",
@ -18,14 +18,25 @@ test "it renders the info", %{"/api/v1/instance": info} do
assert String.equivalent?(description, "Pleroma: An efficient and flexible fediverse server") assert String.equivalent?(description, "Pleroma: An efficient and flexible fediverse server")
end end
test "it renders the panel", %{"/instance/panel.html": panel} do test "it renders the panel", %{"/instance/panel.html" => panel} do
assert String.contains?( assert String.contains?(
panel, panel,
"<p>Welcome to <a href=\"https://pleroma.social\" target=\"_blank\">Pleroma!</a></p>" "<p>Welcome to <a href=\"https://pleroma.social\" target=\"_blank\">Pleroma!</a></p>"
) )
end end
test "it renders the node_info", %{"/nodeinfo/2.0": nodeinfo} do test "it works with overrides" do
clear_config([:instance, :static_dir], "test/fixtures/preload_static")
%{"/instance/panel.html" => panel} = Instance.generate_terms(nil)
assert String.contains?(
panel,
"HEY!"
)
end
test "it renders the node_info", %{"/nodeinfo/2.0.json" => nodeinfo} do
%{ %{
metadata: metadata, metadata: metadata,
version: "2.0" version: "2.0"

View file

@ -8,7 +8,8 @@ defmodule Pleroma.Web.Preload.Providers.StatusNetTest do
setup do: {:ok, StatusNet.generate_terms(nil)} setup do: {:ok, StatusNet.generate_terms(nil)}
test "it renders the info", %{"/api/statusnet/config.json": info} do test "it renders the info", %{"/api/statusnet/config.json" => info} do
assert info =~ "<name>Pleroma</name>" assert {:ok, res} = Jason.decode(info)
assert res["site"]
end end
end end

View file

@ -9,7 +9,7 @@ defmodule Pleroma.Web.Preload.Providers.TimelineTest do
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
alias Pleroma.Web.Preload.Providers.Timelines alias Pleroma.Web.Preload.Providers.Timelines
@public_url :"/api/v1/timelines/public" @public_url "/api/v1/timelines/public"
describe "unauthenticated timeliness when restricted" do describe "unauthenticated timeliness when restricted" do
setup do setup do

View file

@ -9,13 +9,11 @@ defmodule Pleroma.Web.Preload.Providers.UserTest do
describe "returns empty when user doesn't exist" do describe "returns empty when user doesn't exist" do
test "nil user specified" do test "nil user specified" do
refute User.generate_terms(%{user: nil}) assert User.generate_terms(%{user: nil}) == %{}
|> Map.has_key?("/api/v1/accounts")
end end
test "missing user specified" do test "missing user specified" do
refute User.generate_terms(%{user: :not_a_user}) assert User.generate_terms(%{user: :not_a_user}) == %{}
|> Map.has_key?("/api/v1/accounts")
end end
end end
@ -23,11 +21,13 @@ test "missing user specified" do
setup do setup do
user = insert(:user) user = insert(:user)
{:ok, User.generate_terms(%{user: user})} terms = User.generate_terms(%{user: user})
%{terms: terms, user: user}
end end
test "account is rendered", %{"/api/v1/accounts": accounts} do test "account is rendered", %{terms: terms, user: user} do
assert %{acct: user, username: user} = accounts account = terms["/api/v1/accounts/#{user.id}"]
assert %{acct: user, username: user} = account
end end
end end
end end

View file

@ -116,6 +116,35 @@ test "it streams boosts of the user in the 'user' stream", %{user: user} do
refute Streamer.filtered_by_user?(user, announce) refute Streamer.filtered_by_user?(user, announce)
end end
test "it does not stream announces of the user's own posts in the 'user' stream", %{
user: user
} do
Streamer.get_topic_and_add_socket("user", user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, announce} = CommonAPI.repeat(activity.id, other_user)
assert Streamer.filtered_by_user?(user, announce)
end
test "it does stream notifications announces of the user's own posts in the 'user' stream", %{
user: user
} do
Streamer.get_topic_and_add_socket("user", user)
other_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
{:ok, announce} = CommonAPI.repeat(activity.id, other_user)
notification =
Pleroma.Notification
|> Repo.get_by(%{user_id: user.id, activity_id: announce.id})
|> Repo.preload(:activity)
refute Streamer.filtered_by_user?(user, notification)
end
test "it streams boosts of mastodon user in the 'user' stream", %{user: user} do test "it streams boosts of mastodon user in the 'user' stream", %{user: user} do
Streamer.get_topic_and_add_socket("user", user) Streamer.get_topic_and_add_socket("user", user)