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