Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

785 lines
26KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.ApiSpec.AccountOperation do
  5. alias OpenApiSpex.Operation
  6. alias OpenApiSpex.Reference
  7. alias OpenApiSpex.Schema
  8. alias Pleroma.Web.ApiSpec.Schemas.Account
  9. alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship
  10. alias Pleroma.Web.ApiSpec.Schemas.ActorType
  11. alias Pleroma.Web.ApiSpec.Schemas.ApiError
  12. alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
  13. alias Pleroma.Web.ApiSpec.Schemas.List
  14. alias Pleroma.Web.ApiSpec.Schemas.Status
  15. alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
  16. import Pleroma.Web.ApiSpec.Helpers
  17. @spec open_api_operation(atom) :: Operation.t()
  18. def open_api_operation(action) do
  19. operation = String.to_existing_atom("#{action}_operation")
  20. apply(__MODULE__, operation, [])
  21. end
  22. @spec create_operation() :: Operation.t()
  23. def create_operation do
  24. %Operation{
  25. tags: ["accounts"],
  26. summary: "Register an account",
  27. description:
  28. "Creates a user and account records. Returns an account access token for the app that initiated the request. The app should save this token for later, and should wait for the user to confirm their account by clicking a link in their email inbox.",
  29. operationId: "AccountController.create",
  30. requestBody: request_body("Parameters", create_request(), required: true),
  31. responses: %{
  32. 200 => Operation.response("Account", "application/json", create_response()),
  33. 400 => Operation.response("Error", "application/json", ApiError),
  34. 403 => Operation.response("Error", "application/json", ApiError),
  35. 429 => Operation.response("Error", "application/json", ApiError)
  36. }
  37. }
  38. end
  39. def verify_credentials_operation do
  40. %Operation{
  41. tags: ["accounts"],
  42. description: "Test to make sure that the user token works.",
  43. summary: "Verify account credentials",
  44. operationId: "AccountController.verify_credentials",
  45. security: [%{"oAuth" => ["read:accounts"]}],
  46. responses: %{
  47. 200 => Operation.response("Account", "application/json", Account)
  48. }
  49. }
  50. end
  51. def update_credentials_operation do
  52. %Operation{
  53. tags: ["accounts"],
  54. summary: "Update account credentials",
  55. description: "Update the user's display and preferences.",
  56. operationId: "AccountController.update_credentials",
  57. security: [%{"oAuth" => ["write:accounts"]}],
  58. requestBody: request_body("Parameters", update_credentials_request(), required: true),
  59. responses: %{
  60. 200 => Operation.response("Account", "application/json", Account),
  61. 403 => Operation.response("Error", "application/json", ApiError)
  62. }
  63. }
  64. end
  65. def relationships_operation do
  66. %Operation{
  67. tags: ["accounts"],
  68. summary: "Check relationships to other accounts",
  69. operationId: "AccountController.relationships",
  70. description: "Find out whether a given account is followed, blocked, muted, etc.",
  71. security: [%{"oAuth" => ["read:follows"]}],
  72. parameters: [
  73. Operation.parameter(
  74. :id,
  75. :query,
  76. %Schema{
  77. oneOf: [%Schema{type: :array, items: %Schema{type: :string}}, %Schema{type: :string}]
  78. },
  79. "Account IDs",
  80. example: "123"
  81. )
  82. ],
  83. responses: %{
  84. 200 => Operation.response("Account", "application/json", array_of_relationships())
  85. }
  86. }
  87. end
  88. def show_operation do
  89. %Operation{
  90. tags: ["accounts"],
  91. summary: "Account",
  92. operationId: "AccountController.show",
  93. description: "View information about a profile.",
  94. parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
  95. responses: %{
  96. 200 => Operation.response("Account", "application/json", Account),
  97. 401 => Operation.response("Error", "application/json", ApiError),
  98. 404 => Operation.response("Error", "application/json", ApiError)
  99. }
  100. }
  101. end
  102. def statuses_operation do
  103. %Operation{
  104. tags: ["accounts"],
  105. summary: "Statuses",
  106. operationId: "AccountController.statuses",
  107. description:
  108. "Statuses posted to the given account. Public (for public statuses only), or user token + `read:statuses` (for private statuses the user is authorized to see)",
  109. parameters:
  110. [
  111. %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
  112. Operation.parameter(:pinned, :query, BooleanLike, "Include only pinned statuses"),
  113. Operation.parameter(:tagged, :query, :string, "With tag"),
  114. Operation.parameter(
  115. :only_media,
  116. :query,
  117. BooleanLike,
  118. "Include only statuses with media attached"
  119. ),
  120. Operation.parameter(
  121. :with_muted,
  122. :query,
  123. BooleanLike,
  124. "Include statuses from muted acccounts."
  125. ),
  126. Operation.parameter(:exclude_reblogs, :query, BooleanLike, "Exclude reblogs"),
  127. Operation.parameter(:exclude_replies, :query, BooleanLike, "Exclude replies"),
  128. Operation.parameter(
  129. :exclude_visibilities,
  130. :query,
  131. %Schema{type: :array, items: VisibilityScope},
  132. "Exclude visibilities"
  133. )
  134. ] ++ pagination_params(),
  135. responses: %{
  136. 200 => Operation.response("Statuses", "application/json", array_of_statuses()),
  137. 401 => Operation.response("Error", "application/json", ApiError),
  138. 404 => Operation.response("Error", "application/json", ApiError)
  139. }
  140. }
  141. end
  142. def followers_operation do
  143. %Operation{
  144. tags: ["accounts"],
  145. summary: "Followers",
  146. operationId: "AccountController.followers",
  147. security: [%{"oAuth" => ["read:accounts"]}],
  148. description:
  149. "Accounts which follow the given account, if network is not hidden by the account owner.",
  150. parameters: [
  151. %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
  152. Operation.parameter(:id, :query, :string, "ID of the resource owner"),
  153. with_relationships_param() | pagination_params()
  154. ],
  155. responses: %{
  156. 200 => Operation.response("Accounts", "application/json", array_of_accounts())
  157. }
  158. }
  159. end
  160. def following_operation do
  161. %Operation{
  162. tags: ["accounts"],
  163. summary: "Following",
  164. operationId: "AccountController.following",
  165. security: [%{"oAuth" => ["read:accounts"]}],
  166. description:
  167. "Accounts which the given account is following, if network is not hidden by the account owner.",
  168. parameters: [
  169. %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
  170. Operation.parameter(:id, :query, :string, "ID of the resource owner"),
  171. with_relationships_param() | pagination_params()
  172. ],
  173. responses: %{200 => Operation.response("Accounts", "application/json", array_of_accounts())}
  174. }
  175. end
  176. def lists_operation do
  177. %Operation{
  178. tags: ["accounts"],
  179. summary: "Lists containing this account",
  180. operationId: "AccountController.lists",
  181. security: [%{"oAuth" => ["read:lists"]}],
  182. description: "User lists that you have added this account to.",
  183. parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
  184. responses: %{200 => Operation.response("Lists", "application/json", array_of_lists())}
  185. }
  186. end
  187. def follow_operation do
  188. %Operation{
  189. tags: ["accounts"],
  190. summary: "Follow",
  191. operationId: "AccountController.follow",
  192. security: [%{"oAuth" => ["follow", "write:follows"]}],
  193. description: "Follow the given account",
  194. parameters: [
  195. %Reference{"$ref": "#/components/parameters/accountIdOrNickname"}
  196. ],
  197. requestBody:
  198. request_body(
  199. "Parameters",
  200. %Schema{
  201. type: :object,
  202. properties: %{
  203. reblogs: %Schema{
  204. type: :boolean,
  205. description: "Receive this account's reblogs in home timeline? Defaults to true.",
  206. default: true
  207. }
  208. }
  209. },
  210. required: false
  211. ),
  212. responses: %{
  213. 200 => Operation.response("Relationship", "application/json", AccountRelationship),
  214. 400 => Operation.response("Error", "application/json", ApiError),
  215. 404 => Operation.response("Error", "application/json", ApiError)
  216. }
  217. }
  218. end
  219. def unfollow_operation do
  220. %Operation{
  221. tags: ["accounts"],
  222. summary: "Unfollow",
  223. operationId: "AccountController.unfollow",
  224. security: [%{"oAuth" => ["follow", "write:follows"]}],
  225. description: "Unfollow the given account",
  226. parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
  227. responses: %{
  228. 200 => Operation.response("Relationship", "application/json", AccountRelationship),
  229. 400 => Operation.response("Error", "application/json", ApiError),
  230. 404 => Operation.response("Error", "application/json", ApiError)
  231. }
  232. }
  233. end
  234. def mute_operation do
  235. %Operation{
  236. tags: ["accounts"],
  237. summary: "Mute",
  238. operationId: "AccountController.mute",
  239. security: [%{"oAuth" => ["follow", "write:mutes"]}],
  240. requestBody: request_body("Parameters", mute_request()),
  241. description:
  242. "Mute the given account. Clients should filter statuses and notifications from this account, if received (e.g. due to a boost in the Home timeline).",
  243. parameters: [
  244. %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
  245. Operation.parameter(
  246. :notifications,
  247. :query,
  248. %Schema{allOf: [BooleanLike], default: true},
  249. "Mute notifications in addition to statuses? Defaults to `true`."
  250. ),
  251. Operation.parameter(
  252. :expires_in,
  253. :query,
  254. %Schema{type: :integer, default: 0},
  255. "Expire the mute in `expires_in` seconds. Default 0 for infinity"
  256. )
  257. ],
  258. responses: %{
  259. 200 => Operation.response("Relationship", "application/json", AccountRelationship)
  260. }
  261. }
  262. end
  263. def unmute_operation do
  264. %Operation{
  265. tags: ["accounts"],
  266. summary: "Unmute",
  267. operationId: "AccountController.unmute",
  268. security: [%{"oAuth" => ["follow", "write:mutes"]}],
  269. description: "Unmute the given account.",
  270. parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
  271. responses: %{
  272. 200 => Operation.response("Relationship", "application/json", AccountRelationship)
  273. }
  274. }
  275. end
  276. def block_operation do
  277. %Operation{
  278. tags: ["accounts"],
  279. summary: "Block",
  280. operationId: "AccountController.block",
  281. security: [%{"oAuth" => ["follow", "write:blocks"]}],
  282. description:
  283. "Block the given account. Clients should filter statuses from this account if received (e.g. due to a boost in the Home timeline)",
  284. parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
  285. responses: %{
  286. 200 => Operation.response("Relationship", "application/json", AccountRelationship)
  287. }
  288. }
  289. end
  290. def unblock_operation do
  291. %Operation{
  292. tags: ["accounts"],
  293. summary: "Unblock",
  294. operationId: "AccountController.unblock",
  295. security: [%{"oAuth" => ["follow", "write:blocks"]}],
  296. description: "Unblock the given account.",
  297. parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
  298. responses: %{
  299. 200 => Operation.response("Relationship", "application/json", AccountRelationship)
  300. }
  301. }
  302. end
  303. def follow_by_uri_operation do
  304. %Operation{
  305. tags: ["accounts"],
  306. summary: "Follow by URI",
  307. operationId: "AccountController.follows",
  308. security: [%{"oAuth" => ["follow", "write:follows"]}],
  309. requestBody: request_body("Parameters", follow_by_uri_request(), required: true),
  310. responses: %{
  311. 200 => Operation.response("Account", "application/json", AccountRelationship),
  312. 400 => Operation.response("Error", "application/json", ApiError),
  313. 404 => Operation.response("Error", "application/json", ApiError)
  314. }
  315. }
  316. end
  317. def mutes_operation do
  318. %Operation{
  319. tags: ["accounts"],
  320. summary: "Muted accounts",
  321. operationId: "AccountController.mutes",
  322. description: "Accounts the user has muted.",
  323. security: [%{"oAuth" => ["follow", "read:mutes"]}],
  324. parameters: pagination_params(),
  325. responses: %{
  326. 200 => Operation.response("Accounts", "application/json", array_of_accounts())
  327. }
  328. }
  329. end
  330. def blocks_operation do
  331. %Operation{
  332. tags: ["accounts"],
  333. summary: "Blocked users",
  334. operationId: "AccountController.blocks",
  335. description: "View your blocks. See also accounts/:id/{block,unblock}",
  336. security: [%{"oAuth" => ["read:blocks"]}],
  337. parameters: pagination_params(),
  338. responses: %{
  339. 200 => Operation.response("Accounts", "application/json", array_of_accounts())
  340. }
  341. }
  342. end
  343. def endorsements_operation do
  344. %Operation{
  345. tags: ["accounts"],
  346. summary: "Endorsements",
  347. operationId: "AccountController.endorsements",
  348. description: "Not implemented",
  349. security: [%{"oAuth" => ["read:accounts"]}],
  350. responses: %{
  351. 200 => empty_array_response()
  352. }
  353. }
  354. end
  355. def identity_proofs_operation do
  356. %Operation{
  357. tags: ["accounts"],
  358. summary: "Identity proofs",
  359. operationId: "AccountController.identity_proofs",
  360. # Validators complains about unused path params otherwise
  361. parameters: [
  362. %Reference{"$ref": "#/components/parameters/accountIdOrNickname"}
  363. ],
  364. description: "Not implemented",
  365. responses: %{
  366. 200 => empty_array_response()
  367. }
  368. }
  369. end
  370. defp create_request do
  371. %Schema{
  372. title: "AccountCreateRequest",
  373. description: "POST body for creating an account",
  374. type: :object,
  375. required: [:username, :password, :agreement],
  376. properties: %{
  377. reason: %Schema{
  378. type: :string,
  379. nullable: true,
  380. description:
  381. "Text that will be reviewed by moderators if registrations require manual approval"
  382. },
  383. username: %Schema{type: :string, description: "The desired username for the account"},
  384. email: %Schema{
  385. type: :string,
  386. nullable: true,
  387. description:
  388. "The email address to be used for login. Required when `account_activation_required` is enabled.",
  389. format: :email
  390. },
  391. password: %Schema{
  392. type: :string,
  393. description: "The password to be used for login",
  394. format: :password
  395. },
  396. agreement: %Schema{
  397. allOf: [BooleanLike],
  398. description:
  399. "Whether the user agrees to the local rules, terms, and policies. These should be presented to the user in order to allow them to consent before setting this parameter to TRUE."
  400. },
  401. locale: %Schema{
  402. type: :string,
  403. nullable: true,
  404. description: "The language of the confirmation email that will be sent"
  405. },
  406. # Pleroma-specific properties:
  407. fullname: %Schema{type: :string, nullable: true, description: "Full name"},
  408. bio: %Schema{type: :string, description: "Bio", nullable: true, default: ""},
  409. captcha_solution: %Schema{
  410. type: :string,
  411. nullable: true,
  412. description: "Provider-specific captcha solution"
  413. },
  414. captcha_token: %Schema{
  415. type: :string,
  416. nullable: true,
  417. description: "Provider-specific captcha token"
  418. },
  419. captcha_answer_data: %Schema{
  420. type: :string,
  421. nullable: true,
  422. description: "Provider-specific captcha data"
  423. },
  424. token: %Schema{
  425. type: :string,
  426. nullable: true,
  427. description: "Invite token required when the registrations aren't public"
  428. }
  429. },
  430. example: %{
  431. "username" => "cofe",
  432. "email" => "cofe@example.com",
  433. "password" => "secret",
  434. "agreement" => "true",
  435. "bio" => "☕️"
  436. }
  437. }
  438. end
  439. # Note: this is a token response (if login succeeds!), but there's no oauth operation file yet.
  440. defp create_response do
  441. %Schema{
  442. title: "AccountCreateResponse",
  443. description: "Response schema for an account",
  444. type: :object,
  445. properties: %{
  446. # The response when auto-login on create succeeds (token is issued):
  447. token_type: %Schema{type: :string},
  448. access_token: %Schema{type: :string},
  449. refresh_token: %Schema{type: :string},
  450. scope: %Schema{type: :string},
  451. created_at: %Schema{type: :integer, format: :"date-time"},
  452. me: %Schema{type: :string},
  453. expires_in: %Schema{type: :integer},
  454. #
  455. # The response when registration succeeds but auto-login fails (no token):
  456. identifier: %Schema{type: :string},
  457. message: %Schema{type: :string}
  458. },
  459. # Note: example of successful registration with failed login response:
  460. # example: %{
  461. # "identifier" => "missing_confirmed_email",
  462. # "message" => "You have been registered. Please check your email for further instructions."
  463. # },
  464. example: %{
  465. "token_type" => "Bearer",
  466. "access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk",
  467. "refresh_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzz",
  468. "created_at" => 1_585_918_714,
  469. "expires_in" => 600,
  470. "scope" => "read write follow push",
  471. "me" => "https://gensokyo.2hu/users/raymoo"
  472. }
  473. }
  474. end
  475. defp update_credentials_request do
  476. %Schema{
  477. title: "AccountUpdateCredentialsRequest",
  478. description: "POST body for creating an account",
  479. type: :object,
  480. properties: %{
  481. bot: %Schema{
  482. allOf: [BooleanLike],
  483. nullable: true,
  484. description: "Whether the account has a bot flag."
  485. },
  486. display_name: %Schema{
  487. type: :string,
  488. nullable: true,
  489. description: "The display name to use for the profile."
  490. },
  491. note: %Schema{type: :string, description: "The account bio."},
  492. avatar: %Schema{
  493. type: :string,
  494. nullable: true,
  495. description: "Avatar image encoded using multipart/form-data",
  496. format: :binary
  497. },
  498. header: %Schema{
  499. type: :string,
  500. nullable: true,
  501. description: "Header image encoded using multipart/form-data",
  502. format: :binary
  503. },
  504. locked: %Schema{
  505. allOf: [BooleanLike],
  506. nullable: true,
  507. description: "Whether manual approval of follow requests is required."
  508. },
  509. accepts_chat_messages: %Schema{
  510. allOf: [BooleanLike],
  511. nullable: true,
  512. description: "Whether the user accepts receiving chat messages."
  513. },
  514. fields_attributes: %Schema{
  515. nullable: true,
  516. oneOf: [
  517. %Schema{type: :array, items: attribute_field()},
  518. %Schema{type: :object, additionalProperties: attribute_field()}
  519. ]
  520. },
  521. # NOTE: `source` field is not supported
  522. #
  523. # source: %Schema{
  524. # type: :object,
  525. # properties: %{
  526. # privacy: %Schema{type: :string},
  527. # sensitive: %Schema{type: :boolean},
  528. # language: %Schema{type: :string}
  529. # }
  530. # },
  531. # Pleroma-specific fields
  532. no_rich_text: %Schema{
  533. allOf: [BooleanLike],
  534. nullable: true,
  535. description: "html tags are stripped from all statuses requested from the API"
  536. },
  537. hide_followers: %Schema{
  538. allOf: [BooleanLike],
  539. nullable: true,
  540. description: "user's followers will be hidden"
  541. },
  542. hide_follows: %Schema{
  543. allOf: [BooleanLike],
  544. nullable: true,
  545. description: "user's follows will be hidden"
  546. },
  547. hide_followers_count: %Schema{
  548. allOf: [BooleanLike],
  549. nullable: true,
  550. description: "user's follower count will be hidden"
  551. },
  552. hide_follows_count: %Schema{
  553. allOf: [BooleanLike],
  554. nullable: true,
  555. description: "user's follow count will be hidden"
  556. },
  557. hide_favorites: %Schema{
  558. allOf: [BooleanLike],
  559. nullable: true,
  560. description: "user's favorites timeline will be hidden"
  561. },
  562. show_role: %Schema{
  563. allOf: [BooleanLike],
  564. nullable: true,
  565. description: "user's role (e.g admin, moderator) will be exposed to anyone in the
  566. API"
  567. },
  568. default_scope: VisibilityScope,
  569. pleroma_settings_store: %Schema{
  570. type: :object,
  571. nullable: true,
  572. description: "Opaque user settings to be saved on the backend."
  573. },
  574. skip_thread_containment: %Schema{
  575. allOf: [BooleanLike],
  576. nullable: true,
  577. description: "Skip filtering out broken threads"
  578. },
  579. allow_following_move: %Schema{
  580. allOf: [BooleanLike],
  581. nullable: true,
  582. description: "Allows automatically follow moved following accounts"
  583. },
  584. pleroma_background_image: %Schema{
  585. type: :string,
  586. nullable: true,
  587. description: "Sets the background image of the user.",
  588. format: :binary
  589. },
  590. discoverable: %Schema{
  591. allOf: [BooleanLike],
  592. nullable: true,
  593. description:
  594. "Discovery of this account in search results and other services is allowed."
  595. },
  596. actor_type: ActorType
  597. },
  598. example: %{
  599. bot: false,
  600. display_name: "cofe",
  601. note: "foobar",
  602. fields_attributes: [%{name: "foo", value: "bar"}],
  603. no_rich_text: false,
  604. hide_followers: true,
  605. hide_follows: false,
  606. hide_followers_count: false,
  607. hide_follows_count: false,
  608. hide_favorites: false,
  609. show_role: false,
  610. default_scope: "private",
  611. pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
  612. skip_thread_containment: false,
  613. allow_following_move: false,
  614. discoverable: false,
  615. actor_type: "Person"
  616. }
  617. }
  618. end
  619. def array_of_accounts do
  620. %Schema{
  621. title: "ArrayOfAccounts",
  622. type: :array,
  623. items: Account,
  624. example: [Account.schema().example]
  625. }
  626. end
  627. defp array_of_relationships do
  628. %Schema{
  629. title: "ArrayOfRelationships",
  630. description: "Response schema for account relationships",
  631. type: :array,
  632. items: AccountRelationship,
  633. example: [
  634. %{
  635. "id" => "1",
  636. "following" => true,
  637. "showing_reblogs" => true,
  638. "followed_by" => true,
  639. "blocking" => false,
  640. "blocked_by" => true,
  641. "muting" => false,
  642. "muting_notifications" => false,
  643. "requested" => false,
  644. "domain_blocking" => false,
  645. "subscribing" => false,
  646. "endorsed" => true
  647. },
  648. %{
  649. "id" => "2",
  650. "following" => true,
  651. "showing_reblogs" => true,
  652. "followed_by" => true,
  653. "blocking" => false,
  654. "blocked_by" => true,
  655. "muting" => true,
  656. "muting_notifications" => false,
  657. "requested" => true,
  658. "domain_blocking" => false,
  659. "subscribing" => false,
  660. "endorsed" => false
  661. },
  662. %{
  663. "id" => "3",
  664. "following" => true,
  665. "showing_reblogs" => true,
  666. "followed_by" => true,
  667. "blocking" => true,
  668. "blocked_by" => false,
  669. "muting" => true,
  670. "muting_notifications" => false,
  671. "requested" => false,
  672. "domain_blocking" => true,
  673. "subscribing" => true,
  674. "endorsed" => false
  675. }
  676. ]
  677. }
  678. end
  679. defp follow_by_uri_request do
  680. %Schema{
  681. title: "AccountFollowsRequest",
  682. description: "POST body for muting an account",
  683. type: :object,
  684. properties: %{
  685. uri: %Schema{type: :string, nullable: true, format: :uri}
  686. },
  687. required: [:uri]
  688. }
  689. end
  690. defp mute_request do
  691. %Schema{
  692. title: "AccountMuteRequest",
  693. description: "POST body for muting an account",
  694. type: :object,
  695. properties: %{
  696. notifications: %Schema{
  697. allOf: [BooleanLike],
  698. nullable: true,
  699. description: "Mute notifications in addition to statuses? Defaults to true.",
  700. default: true
  701. },
  702. expires_in: %Schema{
  703. type: :integer,
  704. nullable: true,
  705. description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
  706. default: 0
  707. }
  708. },
  709. example: %{
  710. "notifications" => true,
  711. "expires_in" => 86_400
  712. }
  713. }
  714. end
  715. defp array_of_lists do
  716. %Schema{
  717. title: "ArrayOfLists",
  718. description: "Response schema for lists",
  719. type: :array,
  720. items: List,
  721. example: [
  722. %{"id" => "123", "title" => "my list"},
  723. %{"id" => "1337", "title" => "anotehr list"}
  724. ]
  725. }
  726. end
  727. defp array_of_statuses do
  728. %Schema{
  729. title: "ArrayOfStatuses",
  730. type: :array,
  731. items: Status
  732. }
  733. end
  734. defp attribute_field do
  735. %Schema{
  736. title: "AccountAttributeField",
  737. description: "Request schema for account custom fields",
  738. type: :object,
  739. properties: %{
  740. name: %Schema{type: :string},
  741. value: %Schema{type: :string}
  742. },
  743. required: [:name, :value],
  744. example: %{
  745. "name" => "Website",
  746. "value" => "https://pleroma.com"
  747. }
  748. }
  749. end
  750. end