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