Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel-dms
This commit is contained in:
commit
f012c3a202
38 changed files with 1317 additions and 233 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.BBS.Authenticator do
|
||||
use Sshd.PasswordAuthenticator
|
||||
alias Pleroma.Plugs.AuthenticationPlug
|
||||
alias Pleroma.User
|
||||
|
||||
def authenticate(username, password) do
|
||||
|
|
@ -11,7 +12,7 @@ defmodule Pleroma.BBS.Authenticator do
|
|||
password = to_string(password)
|
||||
|
||||
with %User{} = user <- User.get_by_nickname(username) do
|
||||
Pbkdf2.verify_pass(password, user.password_hash)
|
||||
AuthenticationPlug.checkpw(password, user.password_hash)
|
||||
else
|
||||
_e -> false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ defmodule Pleroma.Constants do
|
|||
"announcement_count",
|
||||
"emoji",
|
||||
"context_id",
|
||||
"deleted_activity_id"
|
||||
"deleted_activity_id",
|
||||
"pleroma_internal"
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ defmodule Pleroma.Docs.JSON do
|
|||
with config <- Pleroma.Config.Loader.read("config/description.exs") do
|
||||
config[:pleroma][:config_description]
|
||||
|> Pleroma.Docs.Generator.convert_to_strings()
|
||||
|> Jason.encode!()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,6 +16,11 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
|
|||
:crypt.crypt(password, password_hash) == password_hash
|
||||
end
|
||||
|
||||
def checkpw(password, "$2" <> _ = password_hash) do
|
||||
# Handle bcrypt passwords for Mastodon migration
|
||||
Bcrypt.verify_pass(password, password_hash)
|
||||
end
|
||||
|
||||
def checkpw(password, "$pbkdf2" <> _ = password_hash) do
|
||||
Pbkdf2.verify_pass(password, password_hash)
|
||||
end
|
||||
|
|
@ -36,7 +41,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
|
|||
} = conn,
|
||||
_
|
||||
) do
|
||||
if Pbkdf2.verify_pass(password, password_hash) do
|
||||
if checkpw(password, password_hash) do
|
||||
conn
|
||||
|> assign(:user, auth_user)
|
||||
|> OAuthScopesPlug.skip_plug()
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ defmodule Pleroma.Upload do
|
|||
end
|
||||
end
|
||||
|
||||
defp prepare_upload(%{"img" => "data:image/" <> image_data}, opts) do
|
||||
defp prepare_upload(%{img: "data:image/" <> image_data}, opts) do
|
||||
parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
|
||||
data = Base.decode64!(parsed["data"], ignore: :whitespace)
|
||||
hash = String.downcase(Base.encode16(:crypto.hash(:sha256, data)))
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
|
||||
require Logger
|
||||
|
||||
@descriptions_json Pleroma.Docs.JSON.compile()
|
||||
@descriptions Pleroma.Docs.JSON.compile()
|
||||
@users_page_size 50
|
||||
|
||||
plug(
|
||||
|
|
@ -897,9 +897,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
end
|
||||
|
||||
def config_descriptions(conn, _params) do
|
||||
conn
|
||||
|> Plug.Conn.put_resp_content_type("application/json")
|
||||
|> Plug.Conn.send_resp(200, @descriptions_json)
|
||||
descriptions = Enum.filter(@descriptions, &whitelisted_config?/1)
|
||||
|
||||
json(conn, descriptions)
|
||||
end
|
||||
|
||||
def config_show(conn, %{"only_db" => true}) do
|
||||
|
|
@ -954,7 +954,9 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
def config_update(conn, %{"configs" => configs}) do
|
||||
with :ok <- configurable_from_database(conn) do
|
||||
{_errors, results} =
|
||||
Enum.map(configs, fn
|
||||
configs
|
||||
|> Enum.filter(&whitelisted_config?/1)
|
||||
|> Enum.map(fn
|
||||
%{"group" => group, "key" => key, "delete" => true} = params ->
|
||||
ConfigDB.delete(%{group: group, key: key, subkeys: params["subkeys"]})
|
||||
|
||||
|
|
@ -1016,6 +1018,28 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
|
|||
end
|
||||
end
|
||||
|
||||
defp whitelisted_config?(group, key) do
|
||||
if whitelisted_configs = Config.get(:database_config_whitelist) do
|
||||
Enum.any?(whitelisted_configs, fn
|
||||
{whitelisted_group} ->
|
||||
group == inspect(whitelisted_group)
|
||||
|
||||
{whitelisted_group, whitelisted_key} ->
|
||||
group == inspect(whitelisted_group) && key == inspect(whitelisted_key)
|
||||
end)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
defp whitelisted_config?(%{"group" => group, "key" => key}) do
|
||||
whitelisted_config?(group, key)
|
||||
end
|
||||
|
||||
defp whitelisted_config?(%{:group => group} = config) do
|
||||
whitelisted_config?(group, config[:key])
|
||||
end
|
||||
|
||||
def reload_emoji(conn, _params) do
|
||||
Pleroma.Emoji.reload()
|
||||
|
||||
|
|
|
|||
|
|
@ -54,4 +54,8 @@ defmodule Pleroma.Web.ApiSpec.Helpers do
|
|||
def empty_array_response do
|
||||
Operation.response("Empty array", "application/json", %Schema{type: :array, example: []})
|
||||
end
|
||||
|
||||
def no_content_response do
|
||||
Operation.response("No Content", "application/json", %Schema{type: :string, example: ""})
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -367,15 +367,18 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
title: "AccountCreateRequest",
|
||||
description: "POST body for creating an account",
|
||||
type: :object,
|
||||
required: [:username, :password, :agreement],
|
||||
properties: %{
|
||||
reason: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description:
|
||||
"Text that will be reviewed by moderators if registrations require manual approval"
|
||||
},
|
||||
username: %Schema{type: :string, description: "The desired username for the account"},
|
||||
email: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description:
|
||||
"The email address to be used for login. Required when `account_activation_required` is enabled.",
|
||||
format: :email
|
||||
|
|
@ -392,23 +395,33 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
},
|
||||
locale: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "The language of the confirmation email that will be sent"
|
||||
},
|
||||
# Pleroma-specific properties:
|
||||
fullname: %Schema{type: :string, description: "Full name"},
|
||||
bio: %Schema{type: :string, description: "Bio", default: ""},
|
||||
fullname: %Schema{type: :string, nullable: true, description: "Full name"},
|
||||
bio: %Schema{type: :string, description: "Bio", nullable: true, default: ""},
|
||||
captcha_solution: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Provider-specific captcha solution"
|
||||
},
|
||||
captcha_token: %Schema{type: :string, description: "Provider-specific captcha token"},
|
||||
captcha_answer_data: %Schema{type: :string, description: "Provider-specific captcha data"},
|
||||
captcha_token: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Provider-specific captcha token"
|
||||
},
|
||||
captcha_answer_data: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Provider-specific captcha data"
|
||||
},
|
||||
token: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Invite token required when the registrations aren't public"
|
||||
}
|
||||
},
|
||||
required: [:username, :password, :agreement],
|
||||
example: %{
|
||||
"username" => "cofe",
|
||||
"email" => "cofe@example.com",
|
||||
|
|
@ -447,28 +460,34 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
properties: %{
|
||||
bot: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Whether the account has a bot flag."
|
||||
},
|
||||
display_name: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "The display name to use for the profile."
|
||||
},
|
||||
note: %Schema{type: :string, description: "The account bio."},
|
||||
avatar: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Avatar image encoded using multipart/form-data",
|
||||
format: :binary
|
||||
},
|
||||
header: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Header image encoded using multipart/form-data",
|
||||
format: :binary
|
||||
},
|
||||
locked: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Whether manual approval of follow requests is required."
|
||||
},
|
||||
fields_attributes: %Schema{
|
||||
nullable: true,
|
||||
oneOf: [
|
||||
%Schema{type: :array, items: attribute_field()},
|
||||
%Schema{type: :object, additionalProperties: %Schema{type: attribute_field()}}
|
||||
|
|
@ -488,47 +507,65 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
# Pleroma-specific fields
|
||||
no_rich_text: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "html tags are stripped from all statuses requested from the API"
|
||||
},
|
||||
hide_followers: %Schema{type: :boolean, description: "user's followers will be hidden"},
|
||||
hide_follows: %Schema{type: :boolean, description: "user's follows will be hidden"},
|
||||
hide_followers: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "user's followers will be hidden"
|
||||
},
|
||||
hide_follows: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "user's follows will be hidden"
|
||||
},
|
||||
hide_followers_count: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "user's follower count will be hidden"
|
||||
},
|
||||
hide_follows_count: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "user's follow count will be hidden"
|
||||
},
|
||||
hide_favorites: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "user's favorites timeline will be hidden"
|
||||
},
|
||||
show_role: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "user's role (e.g admin, moderator) will be exposed to anyone in the
|
||||
API"
|
||||
},
|
||||
default_scope: VisibilityScope,
|
||||
pleroma_settings_store: %Schema{
|
||||
type: :object,
|
||||
nullable: true,
|
||||
description: "Opaque user settings to be saved on the backend."
|
||||
},
|
||||
skip_thread_containment: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Skip filtering out broken threads"
|
||||
},
|
||||
allow_following_move: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Allows automatically follow moved following accounts"
|
||||
},
|
||||
pleroma_background_image: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Sets the background image of the user.",
|
||||
format: :binary
|
||||
},
|
||||
discoverable: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description:
|
||||
"Discovery of this account in search results and other services is allowed."
|
||||
},
|
||||
|
|
@ -624,7 +661,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
description: "POST body for muting an account",
|
||||
type: :object,
|
||||
properties: %{
|
||||
uri: %Schema{type: :string, format: :uri}
|
||||
uri: %Schema{type: :string, nullable: true, format: :uri}
|
||||
},
|
||||
required: [:uri]
|
||||
}
|
||||
|
|
@ -638,6 +675,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
|
|||
properties: %{
|
||||
notifications: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Mute notifications in addition to statuses? Defaults to true.",
|
||||
default: true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,7 +105,11 @@ defmodule Pleroma.Web.ApiSpec.AppOperation do
|
|||
description: "Space separated list of scopes",
|
||||
default: "read"
|
||||
},
|
||||
website: %Schema{type: :string, description: "A URL to the homepage of your app"}
|
||||
website: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "A URL to the homepage of your app"
|
||||
}
|
||||
},
|
||||
required: [:client_name, :redirect_uris],
|
||||
example: %{
|
||||
|
|
|
|||
|
|
@ -199,12 +199,14 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
|
|||
"Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified."
|
||||
},
|
||||
irreversible: %Schema{
|
||||
type: :bolean,
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description:
|
||||
"Should the server irreversibly drop matching entities from home and notifications?"
|
||||
},
|
||||
whole_word: %Schema{
|
||||
type: :bolean,
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Consider word boundaries?",
|
||||
default: true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,14 +110,16 @@ defmodule Pleroma.Web.ApiSpec.MarkerOperation do
|
|||
properties: %{
|
||||
notifications: %Schema{
|
||||
type: :object,
|
||||
nullable: true,
|
||||
properties: %{
|
||||
last_read_id: %Schema{type: :string}
|
||||
last_read_id: %Schema{nullable: true, type: :string}
|
||||
}
|
||||
},
|
||||
home: %Schema{
|
||||
type: :object,
|
||||
nullable: true,
|
||||
properties: %{
|
||||
last_read_id: %Schema{type: :string}
|
||||
last_read_id: %Schema{nullable: true, type: :string}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
187
lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex
Normal file
187
lib/pleroma/web/api_spec/operations/pleroma_account_operation.ex
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||
alias Pleroma.Web.ApiSpec.StatusOperation
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def confirmation_resend_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Resend confirmation email. Expects `email` or `nickname`",
|
||||
operationId: "PleromaAPI.AccountController.confirmation_resend",
|
||||
parameters: [
|
||||
Operation.parameter(:email, :query, :string, "Email of that needs to be verified",
|
||||
example: "cofe@cofe.io"
|
||||
),
|
||||
Operation.parameter(
|
||||
:nickname,
|
||||
:query,
|
||||
:string,
|
||||
"Nickname of user that needs to be verified",
|
||||
example: "cofefe"
|
||||
)
|
||||
],
|
||||
responses: %{
|
||||
204 => no_content_response()
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_avatar_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Set/clear user avatar image",
|
||||
operationId: "PleromaAPI.AccountController.update_avatar",
|
||||
requestBody:
|
||||
request_body("Parameters", update_avatar_or_background_request(), required: true),
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
responses: %{
|
||||
200 => update_response(),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_banner_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Set/clear user banner image",
|
||||
operationId: "PleromaAPI.AccountController.update_banner",
|
||||
requestBody: request_body("Parameters", update_banner_request(), required: true),
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
responses: %{
|
||||
200 => update_response()
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_background_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Set/clear user background image",
|
||||
operationId: "PleromaAPI.AccountController.update_background",
|
||||
security: [%{"oAuth" => ["write:accounts"]}],
|
||||
requestBody:
|
||||
request_body("Parameters", update_avatar_or_background_request(), required: true),
|
||||
responses: %{
|
||||
200 => update_response()
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def favourites_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Returns favorites timeline of any user",
|
||||
operationId: "PleromaAPI.AccountController.favourites",
|
||||
parameters: [id_param() | pagination_params()],
|
||||
security: [%{"oAuth" => ["read:favourites"]}],
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response(
|
||||
"Array of Statuses",
|
||||
"application/json",
|
||||
StatusOperation.array_of_statuses()
|
||||
),
|
||||
403 => Operation.response("Forbidden", "application/json", ApiError),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def subscribe_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Subscribe to receive notifications for all statuses posted by a user",
|
||||
operationId: "PleromaAPI.AccountController.subscribe",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["follow", "write:follows"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Relationship", "application/json", AccountRelationship),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def unsubscribe_operation do
|
||||
%Operation{
|
||||
tags: ["Accounts"],
|
||||
summary: "Unsubscribe to stop receiving notifications from user statuses",
|
||||
operationId: "PleromaAPI.AccountController.unsubscribe",
|
||||
parameters: [id_param()],
|
||||
security: [%{"oAuth" => ["follow", "write:follows"]}],
|
||||
responses: %{
|
||||
200 => Operation.response("Relationship", "application/json", AccountRelationship),
|
||||
404 => Operation.response("Not Found", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, FlakeID, "Account ID",
|
||||
example: "9umDrYheeY451cQnEe",
|
||||
required: true
|
||||
)
|
||||
end
|
||||
|
||||
defp update_avatar_or_background_request do
|
||||
%Schema{
|
||||
title: "PleromaAccountUpdateAvatarOrBackgroundRequest",
|
||||
type: :object,
|
||||
properties: %{
|
||||
img: %Schema{
|
||||
nullable: true,
|
||||
type: :string,
|
||||
format: :binary,
|
||||
description: "Image encoded using `multipart/form-data` or an empty string to clear"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp update_banner_request do
|
||||
%Schema{
|
||||
title: "PleromaAccountUpdateBannerRequest",
|
||||
type: :object,
|
||||
properties: %{
|
||||
banner: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
format: :binary,
|
||||
description: "Image encoded using `multipart/form-data` or an empty string to clear"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp update_response do
|
||||
Operation.response("PleromaAccountUpdateResponse", "application/json", %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
url: %Schema{
|
||||
type: :string,
|
||||
format: :uri,
|
||||
nullable: true,
|
||||
description: "Image URL"
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
"url" =>
|
||||
"https://cofe.party/media/9d0add56-bcb6-4c0f-8225-cbbd0b6dd773/13eadb6972c9ccd3f4ffa3b8196f0e0d38b4d2f27594457c52e52946c054cd9a.gif"
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
@ -37,15 +37,18 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
|
|||
account_id: %Schema{type: :string, description: "ID of the account to report"},
|
||||
status_ids: %Schema{
|
||||
type: :array,
|
||||
nullable: true,
|
||||
items: %Schema{type: :string},
|
||||
description: "Array of Statuses to attach to the report, for context"
|
||||
},
|
||||
comment: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "Reason for the report"
|
||||
},
|
||||
forward: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
default: false,
|
||||
description:
|
||||
"If the account is remote, should the report be forwarded to the remote admin?"
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
}
|
||||
end
|
||||
|
||||
defp array_of_statuses do
|
||||
def array_of_statuses do
|
||||
%Schema{type: :array, items: Status, example: [Status.schema().example]}
|
||||
end
|
||||
|
||||
|
|
@ -371,15 +371,18 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
properties: %{
|
||||
status: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description:
|
||||
"Text content of the status. If `media_ids` is provided, this becomes optional. Attaching a `poll` is optional while `status` is provided."
|
||||
},
|
||||
media_ids: %Schema{
|
||||
nullable: true,
|
||||
type: :array,
|
||||
items: %Schema{type: :string},
|
||||
description: "Array of Attachment ids to be attached as media."
|
||||
},
|
||||
poll: %Schema{
|
||||
nullable: true,
|
||||
type: :object,
|
||||
required: [:options],
|
||||
properties: %{
|
||||
|
|
@ -390,26 +393,35 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
},
|
||||
expires_in: %Schema{
|
||||
type: :integer,
|
||||
nullable: true,
|
||||
description:
|
||||
"Duration the poll should be open, in seconds. Must be provided with `poll[options]`"
|
||||
},
|
||||
multiple: %Schema{type: :boolean, description: "Allow multiple choices?"},
|
||||
multiple: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Allow multiple choices?"
|
||||
},
|
||||
hide_totals: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Hide vote counts until the poll ends?"
|
||||
}
|
||||
}
|
||||
},
|
||||
in_reply_to_id: %Schema{
|
||||
nullable: true,
|
||||
allOf: [FlakeID],
|
||||
description: "ID of the status being replied to, if status is a reply"
|
||||
},
|
||||
sensitive: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Mark status and attached media as sensitive?"
|
||||
},
|
||||
spoiler_text: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description:
|
||||
"Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field."
|
||||
},
|
||||
|
|
@ -420,25 +432,33 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
description:
|
||||
"ISO 8601 Datetime at which to schedule a status. Providing this paramter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future."
|
||||
},
|
||||
language: %Schema{type: :string, description: "ISO 639 language code for this status."},
|
||||
language: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description: "ISO 639 language code for this status."
|
||||
},
|
||||
# Pleroma-specific properties:
|
||||
preview: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description:
|
||||
"If set to `true` the post won't be actually posted, but the status entitiy would still be rendered back. This could be useful for previewing rich text/custom emoji, for example"
|
||||
},
|
||||
content_type: %Schema{
|
||||
type: :string,
|
||||
nullable: true,
|
||||
description:
|
||||
"The MIME type of the status, it is transformed into HTML by the backend. You can get the list of the supported MIME types with the nodeinfo endpoint."
|
||||
},
|
||||
to: %Schema{
|
||||
type: :array,
|
||||
nullable: true,
|
||||
items: %Schema{type: :string},
|
||||
description:
|
||||
"A list of nicknames (like `lain@soykaf.club` or `lain` on the local server) that will be used to determine who is going to be addressed by this post. Using this will disable the implicit addressing by mentioned names in the `status` body, only the people in the `to` list will be addressed. The normal rules for for post visibility are not affected by this and will still apply"
|
||||
},
|
||||
visibility: %Schema{
|
||||
nullable: true,
|
||||
anyOf: [
|
||||
VisibilityScope,
|
||||
%Schema{type: :string, description: "`list:LIST_ID`", example: "LIST:123"}
|
||||
|
|
@ -447,11 +467,13 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
|
|||
"Visibility of the posted status. Besides standard MastoAPI values (`direct`, `private`, `unlisted` or `public`) it can be used to address a List by setting it to `list:LIST_ID`"
|
||||
},
|
||||
expires_in: %Schema{
|
||||
nullable: true,
|
||||
type: :integer,
|
||||
description:
|
||||
"The number of seconds the posted activity should expire in. When a posted activity expires it will be deleted from the server, and a delete request for it will be federated. This needs to be longer than an hour."
|
||||
},
|
||||
in_reply_to_conversation_id: %Schema{
|
||||
nullable: true,
|
||||
type: :string,
|
||||
description:
|
||||
"Will reply to a given conversation, addressing only the people who are part of the recipient set of that conversation. Sets the visibility to `direct`."
|
||||
|
|
|
|||
|
|
@ -109,19 +109,38 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
|
|||
required: [:endpoint, :keys]
|
||||
},
|
||||
data: %Schema{
|
||||
nullable: true,
|
||||
type: :object,
|
||||
properties: %{
|
||||
alerts: %Schema{
|
||||
nullable: true,
|
||||
type: :object,
|
||||
properties: %{
|
||||
follow: %Schema{type: :boolean, description: "Receive follow notifications?"},
|
||||
follow: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive follow notifications?"
|
||||
},
|
||||
favourite: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive favourite notifications?"
|
||||
},
|
||||
reblog: %Schema{type: :boolean, description: "Receive reblog notifications?"},
|
||||
mention: %Schema{type: :boolean, description: "Receive mention notifications?"},
|
||||
poll: %Schema{type: :boolean, description: "Receive poll notifications?"}
|
||||
reblog: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive reblog notifications?"
|
||||
},
|
||||
mention: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive mention notifications?"
|
||||
},
|
||||
poll: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive poll notifications?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -154,19 +173,38 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
|
|||
type: :object,
|
||||
properties: %{
|
||||
data: %Schema{
|
||||
nullable: true,
|
||||
type: :object,
|
||||
properties: %{
|
||||
alerts: %Schema{
|
||||
nullable: true,
|
||||
type: :object,
|
||||
properties: %{
|
||||
follow: %Schema{type: :boolean, description: "Receive follow notifications?"},
|
||||
follow: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive follow notifications?"
|
||||
},
|
||||
favourite: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive favourite notifications?"
|
||||
},
|
||||
reblog: %Schema{type: :boolean, description: "Receive reblog notifications?"},
|
||||
mention: %Schema{type: :boolean, description: "Receive mention notifications?"},
|
||||
poll: %Schema{type: :boolean, description: "Receive poll notifications?"}
|
||||
reblog: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive reblog notifications?"
|
||||
},
|
||||
mention: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive mention notifications?"
|
||||
},
|
||||
poll: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description: "Receive poll notifications?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.Auth.TOTPAuthenticator do
|
||||
alias Pleroma.MFA
|
||||
alias Pleroma.MFA.TOTP
|
||||
alias Pleroma.Plugs.AuthenticationPlug
|
||||
alias Pleroma.User
|
||||
|
||||
@doc "Verify code or check backup code."
|
||||
|
|
@ -30,7 +31,7 @@ defmodule Pleroma.Web.Auth.TOTPAuthenticator do
|
|||
code
|
||||
)
|
||||
when is_list(codes) and is_binary(code) do
|
||||
hash_code = Enum.find(codes, fn hash -> Pbkdf2.verify_pass(code, hash) end)
|
||||
hash_code = Enum.find(codes, fn hash -> AuthenticationPlug.checkpw(code, hash) end)
|
||||
|
||||
if hash_code do
|
||||
MFA.invalidate_backup_code(user, hash_code)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.MongooseIM.MongooseIMController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.Plugs.AuthenticationPlug
|
||||
alias Pleroma.Plugs.RateLimiter
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.User
|
||||
|
|
@ -27,7 +28,7 @@ defmodule Pleroma.Web.MongooseIM.MongooseIMController do
|
|||
def check_password(conn, %{"user" => username, "pass" => password}) do
|
||||
with %User{password_hash: password_hash, deactivated: false} <-
|
||||
Repo.get_by(User, nickname: username, local: true),
|
||||
true <- Pbkdf2.verify_pass(password, password_hash) do
|
||||
true <- AuthenticationPlug.checkpw(password, password_hash) do
|
||||
conn
|
||||
|> json(true)
|
||||
else
|
||||
|
|
|
|||
|
|
@ -18,6 +18,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
|
||||
require Pleroma.Constants
|
||||
|
||||
plug(
|
||||
OpenApiSpex.Plug.PutApiSpec,
|
||||
[module: Pleroma.Web.ApiSpec] when action == :confirmation_resend
|
||||
)
|
||||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
|
||||
plug(
|
||||
:skip_plug,
|
||||
[OAuthScopesPlug, EnsurePublicOrAuthenticatedPlug] when action == :confirmation_resend
|
||||
|
|
@ -49,9 +56,11 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe])
|
||||
plug(:put_view, Pleroma.Web.MastodonAPI.AccountView)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaAccountOperation
|
||||
|
||||
@doc "POST /api/v1/pleroma/accounts/confirmation_resend"
|
||||
def confirmation_resend(conn, params) do
|
||||
nickname_or_email = params["email"] || params["nickname"]
|
||||
nickname_or_email = params[:email] || params[:nickname]
|
||||
|
||||
with %User{} = user <- User.get_by_nickname_or_email(nickname_or_email),
|
||||
{:ok, _} <- User.try_send_confirmation_email(user) do
|
||||
|
|
@ -60,7 +69,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
end
|
||||
|
||||
@doc "PATCH /api/v1/pleroma/accounts/update_avatar"
|
||||
def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
|
||||
def update_avatar(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do
|
||||
{:ok, _user} =
|
||||
user
|
||||
|> Changeset.change(%{avatar: nil})
|
||||
|
|
@ -69,7 +78,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
json(conn, %{url: nil})
|
||||
end
|
||||
|
||||
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||
def update_avatar(%{assigns: %{user: user}, body_params: params} = conn, _params) do
|
||||
{:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)
|
||||
{:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()
|
||||
%{"url" => [%{"href" => href} | _]} = data
|
||||
|
|
@ -78,14 +87,14 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
end
|
||||
|
||||
@doc "PATCH /api/v1/pleroma/accounts/update_banner"
|
||||
def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
|
||||
def update_banner(%{assigns: %{user: user}, body_params: %{banner: ""}} = conn, _) do
|
||||
with {:ok, _user} <- User.update_banner(user, %{}) do
|
||||
json(conn, %{url: nil})
|
||||
end
|
||||
end
|
||||
|
||||
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
||||
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
|
||||
def update_banner(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
||||
with {:ok, object} <- ActivityPub.upload(%{img: params[:banner]}, type: :banner),
|
||||
{:ok, _user} <- User.update_banner(user, object.data) do
|
||||
%{"url" => [%{"href" => href} | _]} = object.data
|
||||
|
||||
|
|
@ -94,13 +103,13 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
end
|
||||
|
||||
@doc "PATCH /api/v1/pleroma/accounts/update_background"
|
||||
def update_background(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
|
||||
def update_background(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do
|
||||
with {:ok, _user} <- User.update_background(user, %{}) do
|
||||
json(conn, %{url: nil})
|
||||
end
|
||||
end
|
||||
|
||||
def update_background(%{assigns: %{user: user}} = conn, params) do
|
||||
def update_background(%{assigns: %{user: user}, body_params: params} = conn, _) do
|
||||
with {:ok, object} <- ActivityPub.upload(params, type: :background),
|
||||
{:ok, _user} <- User.update_background(user, object.data) do
|
||||
%{"url" => [%{"href" => href} | _]} = object.data
|
||||
|
|
@ -117,6 +126,7 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
|||
def favourites(%{assigns: %{user: for_user, account: user}} = conn, params) do
|
||||
params =
|
||||
params
|
||||
|> Map.new(fn {key, value} -> {to_string(key), value} end)
|
||||
|> Map.put("type", "Create")
|
||||
|> Map.put("favorited_by", user.ap_id)
|
||||
|> Map.put("blocking_user", for_user)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue