Respect restrict_unauthenticated in /api/v1/accounts/lookup
[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 401 => Operation.response("Error", "application/json", ApiError),
436 404 => Operation.response("Error", "application/json", ApiError)
437 }
438 }
439 end
440
441 def endorsements_operation do
442 %Operation{
443 tags: ["Retrieve account information"],
444 summary: "Endorsements",
445 operationId: "AccountController.endorsements",
446 description: "Not implemented",
447 security: [%{"oAuth" => ["read:accounts"]}],
448 responses: %{
449 200 => empty_array_response()
450 }
451 }
452 end
453
454 def identity_proofs_operation do
455 %Operation{
456 tags: ["Retrieve account information"],
457 summary: "Identity proofs",
458 operationId: "AccountController.identity_proofs",
459 # Validators complains about unused path params otherwise
460 parameters: [
461 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"}
462 ],
463 description: "Not implemented",
464 responses: %{
465 200 => empty_array_response()
466 }
467 }
468 end
469
470 defp create_request do
471 %Schema{
472 title: "AccountCreateRequest",
473 description: "POST body for creating an account",
474 type: :object,
475 required: [:username, :password, :agreement],
476 properties: %{
477 reason: %Schema{
478 type: :string,
479 nullable: true,
480 description:
481 "Text that will be reviewed by moderators if registrations require manual approval"
482 },
483 username: %Schema{type: :string, description: "The desired username for the account"},
484 email: %Schema{
485 type: :string,
486 nullable: true,
487 description:
488 "The email address to be used for login. Required when `account_activation_required` is enabled.",
489 format: :email
490 },
491 password: %Schema{
492 type: :string,
493 description: "The password to be used for login",
494 format: :password
495 },
496 agreement: %Schema{
497 allOf: [BooleanLike],
498 description:
499 "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."
500 },
501 locale: %Schema{
502 type: :string,
503 nullable: true,
504 description: "The language of the confirmation email that will be sent"
505 },
506 # Pleroma-specific properties:
507 fullname: %Schema{type: :string, nullable: true, description: "Full name"},
508 bio: %Schema{type: :string, description: "Bio", nullable: true, default: ""},
509 captcha_solution: %Schema{
510 type: :string,
511 nullable: true,
512 description: "Provider-specific captcha solution"
513 },
514 captcha_token: %Schema{
515 type: :string,
516 nullable: true,
517 description: "Provider-specific captcha token"
518 },
519 captcha_answer_data: %Schema{
520 type: :string,
521 nullable: true,
522 description: "Provider-specific captcha data"
523 },
524 token: %Schema{
525 type: :string,
526 nullable: true,
527 description: "Invite token required when the registrations aren't public"
528 },
529 language: %Schema{
530 type: :string,
531 nullable: true,
532 description: "User's preferred language for emails"
533 }
534 },
535 example: %{
536 "username" => "cofe",
537 "email" => "cofe@example.com",
538 "password" => "secret",
539 "agreement" => "true",
540 "bio" => "☕️"
541 }
542 }
543 end
544
545 # Note: this is a token response (if login succeeds!), but there's no oauth operation file yet.
546 defp create_response do
547 %Schema{
548 title: "AccountCreateResponse",
549 description: "Response schema for an account",
550 type: :object,
551 properties: %{
552 # The response when auto-login on create succeeds (token is issued):
553 token_type: %Schema{type: :string},
554 access_token: %Schema{type: :string},
555 refresh_token: %Schema{type: :string},
556 scope: %Schema{type: :string},
557 created_at: %Schema{type: :integer, format: :"date-time"},
558 me: %Schema{type: :string},
559 expires_in: %Schema{type: :integer},
560 #
561 # The response when registration succeeds but auto-login fails (no token):
562 identifier: %Schema{type: :string},
563 message: %Schema{type: :string}
564 },
565 # Note: example of successful registration with failed login response:
566 # example: %{
567 # "identifier" => "missing_confirmed_email",
568 # "message" => "You have been registered. Please check your email for further instructions."
569 # },
570 example: %{
571 "token_type" => "Bearer",
572 "access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk",
573 "refresh_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzz",
574 "created_at" => 1_585_918_714,
575 "expires_in" => 600,
576 "scope" => "read write follow push",
577 "me" => "https://gensokyo.2hu/users/raymoo"
578 }
579 }
580 end
581
582 defp update_credentials_request do
583 %Schema{
584 title: "AccountUpdateCredentialsRequest",
585 description: "POST body for creating an account",
586 type: :object,
587 properties: %{
588 bot: %Schema{
589 allOf: [BooleanLike],
590 nullable: true,
591 description: "Whether the account has a bot flag."
592 },
593 display_name: %Schema{
594 type: :string,
595 nullable: true,
596 description: "The display name to use for the profile."
597 },
598 note: %Schema{type: :string, description: "The account bio."},
599 avatar: %Schema{
600 type: :string,
601 nullable: true,
602 description: "Avatar image encoded using multipart/form-data",
603 format: :binary
604 },
605 header: %Schema{
606 type: :string,
607 nullable: true,
608 description: "Header image encoded using multipart/form-data",
609 format: :binary
610 },
611 locked: %Schema{
612 allOf: [BooleanLike],
613 nullable: true,
614 description: "Whether manual approval of follow requests is required."
615 },
616 fields_attributes: %Schema{
617 nullable: true,
618 oneOf: [
619 %Schema{type: :array, items: attribute_field()},
620 %Schema{type: :object, additionalProperties: attribute_field()}
621 ]
622 },
623 # NOTE: `source` field is not supported
624 #
625 # source: %Schema{
626 # type: :object,
627 # properties: %{
628 # privacy: %Schema{type: :string},
629 # sensitive: %Schema{type: :boolean},
630 # language: %Schema{type: :string}
631 # }
632 # },
633
634 # Pleroma-specific fields
635 no_rich_text: %Schema{
636 allOf: [BooleanLike],
637 nullable: true,
638 description: "html tags are stripped from all statuses requested from the API"
639 },
640 hide_followers: %Schema{
641 allOf: [BooleanLike],
642 nullable: true,
643 description: "user's followers will be hidden"
644 },
645 hide_follows: %Schema{
646 allOf: [BooleanLike],
647 nullable: true,
648 description: "user's follows will be hidden"
649 },
650 hide_followers_count: %Schema{
651 allOf: [BooleanLike],
652 nullable: true,
653 description: "user's follower count will be hidden"
654 },
655 hide_follows_count: %Schema{
656 allOf: [BooleanLike],
657 nullable: true,
658 description: "user's follow count will be hidden"
659 },
660 hide_favorites: %Schema{
661 allOf: [BooleanLike],
662 nullable: true,
663 description: "user's favorites timeline will be hidden"
664 },
665 show_role: %Schema{
666 allOf: [BooleanLike],
667 nullable: true,
668 description: "user's role (e.g admin, moderator) will be exposed to anyone in the
669 API"
670 },
671 default_scope: VisibilityScope,
672 pleroma_settings_store: %Schema{
673 type: :object,
674 nullable: true,
675 description: "Opaque user settings to be saved on the backend."
676 },
677 skip_thread_containment: %Schema{
678 allOf: [BooleanLike],
679 nullable: true,
680 description: "Skip filtering out broken threads"
681 },
682 allow_following_move: %Schema{
683 allOf: [BooleanLike],
684 nullable: true,
685 description: "Allows automatically follow moved following accounts"
686 },
687 also_known_as: %Schema{
688 type: :array,
689 items: %Schema{type: :string},
690 nullable: true,
691 description: "List of alternate ActivityPub IDs"
692 },
693 pleroma_background_image: %Schema{
694 type: :string,
695 nullable: true,
696 description: "Sets the background image of the user.",
697 format: :binary
698 },
699 discoverable: %Schema{
700 allOf: [BooleanLike],
701 nullable: true,
702 description:
703 "Discovery (listing, indexing) of this account by external services (search bots etc.) is allowed."
704 },
705 actor_type: ActorType,
706 status_ttl_days: %Schema{
707 type: :integer,
708 nullable: true,
709 description:
710 "Number of days after which statuses will be deleted. Set to -1 to disable."
711 }
712 },
713 example: %{
714 bot: false,
715 display_name: "cofe",
716 note: "foobar",
717 fields_attributes: [%{name: "foo", value: "bar"}],
718 no_rich_text: false,
719 hide_followers: true,
720 hide_follows: false,
721 hide_followers_count: false,
722 hide_follows_count: false,
723 hide_favorites: false,
724 show_role: false,
725 default_scope: "private",
726 pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
727 skip_thread_containment: false,
728 allow_following_move: false,
729 also_known_as: ["https://foo.bar/users/foo"],
730 discoverable: false,
731 actor_type: "Person",
732 status_ttl_days: 30
733 }
734 }
735 end
736
737 def array_of_accounts do
738 %Schema{
739 title: "ArrayOfAccounts",
740 type: :array,
741 items: Account,
742 example: [Account.schema().example]
743 }
744 end
745
746 defp array_of_relationships do
747 %Schema{
748 title: "ArrayOfRelationships",
749 description: "Response schema for account relationships",
750 type: :array,
751 items: AccountRelationship,
752 example: [
753 %{
754 "id" => "1",
755 "following" => true,
756 "showing_reblogs" => true,
757 "followed_by" => true,
758 "blocking" => false,
759 "blocked_by" => true,
760 "muting" => false,
761 "muting_notifications" => false,
762 "note" => "",
763 "requested" => false,
764 "domain_blocking" => false,
765 "subscribing" => false,
766 "notifying" => false,
767 "endorsed" => true
768 },
769 %{
770 "id" => "2",
771 "following" => true,
772 "showing_reblogs" => true,
773 "followed_by" => true,
774 "blocking" => false,
775 "blocked_by" => true,
776 "muting" => true,
777 "muting_notifications" => false,
778 "note" => "",
779 "requested" => true,
780 "domain_blocking" => false,
781 "subscribing" => false,
782 "notifying" => false,
783 "endorsed" => false
784 },
785 %{
786 "id" => "3",
787 "following" => true,
788 "showing_reblogs" => true,
789 "followed_by" => true,
790 "blocking" => true,
791 "blocked_by" => false,
792 "muting" => true,
793 "muting_notifications" => false,
794 "note" => "",
795 "requested" => false,
796 "domain_blocking" => true,
797 "subscribing" => true,
798 "notifying" => true,
799 "endorsed" => false
800 }
801 ]
802 }
803 end
804
805 defp follow_by_uri_request do
806 %Schema{
807 title: "AccountFollowsRequest",
808 description: "POST body for muting an account",
809 type: :object,
810 properties: %{
811 uri: %Schema{type: :string, nullable: true, format: :uri}
812 },
813 required: [:uri]
814 }
815 end
816
817 defp mute_request do
818 %Schema{
819 title: "AccountMuteRequest",
820 description: "POST body for muting an account",
821 type: :object,
822 properties: %{
823 notifications: %Schema{
824 allOf: [BooleanLike],
825 nullable: true,
826 description: "Mute notifications in addition to statuses? Defaults to true.",
827 default: true
828 },
829 expires_in: %Schema{
830 type: :integer,
831 nullable: true,
832 description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
833 default: 0
834 }
835 },
836 example: %{
837 "notifications" => true,
838 "expires_in" => 86_400
839 }
840 }
841 end
842
843 defp note_request do
844 %Schema{
845 title: "AccountNoteRequest",
846 description: "POST body for adding a note for an account",
847 type: :object,
848 properties: %{
849 comment: %Schema{
850 type: :string,
851 description: "Account note body"
852 }
853 },
854 example: %{
855 "comment" => "Example note"
856 }
857 }
858 end
859
860 defp array_of_lists do
861 %Schema{
862 title: "ArrayOfLists",
863 description: "Response schema for lists",
864 type: :array,
865 items: List,
866 example: [
867 %{"id" => "123", "title" => "my list"},
868 %{"id" => "1337", "title" => "anotehr list"}
869 ]
870 }
871 end
872
873 defp array_of_statuses do
874 %Schema{
875 title: "ArrayOfStatuses",
876 type: :array,
877 items: Status
878 }
879 end
880
881 defp attribute_field do
882 %Schema{
883 title: "AccountAttributeField",
884 description: "Request schema for account custom fields",
885 type: :object,
886 properties: %{
887 name: %Schema{type: :string},
888 value: %Schema{type: :string}
889 },
890 required: [:name, :value],
891 example: %{
892 "name" => "Website",
893 "value" => "https://pleroma.com"
894 }
895 }
896 end
897 end