Lint
[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 type: :boolean,
227 description: "Receive this account's reblogs in home timeline? Defaults to true.",
228 default: true
229 }
230 }
231 },
232 required: false
233 ),
234 responses: %{
235 200 => Operation.response("Relationship", "application/json", AccountRelationship),
236 400 => Operation.response("Error", "application/json", ApiError),
237 404 => Operation.response("Error", "application/json", ApiError)
238 }
239 }
240 end
241
242 def unfollow_operation do
243 %Operation{
244 tags: ["Account actions"],
245 summary: "Unfollow",
246 operationId: "AccountController.unfollow",
247 security: [%{"oAuth" => ["follow", "write:follows"]}],
248 description: "Unfollow the given account",
249 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
250 responses: %{
251 200 => Operation.response("Relationship", "application/json", AccountRelationship),
252 400 => Operation.response("Error", "application/json", ApiError),
253 404 => Operation.response("Error", "application/json", ApiError)
254 }
255 }
256 end
257
258 def mute_operation do
259 %Operation{
260 tags: ["Account actions"],
261 summary: "Mute",
262 operationId: "AccountController.mute",
263 security: [%{"oAuth" => ["follow", "write:mutes"]}],
264 requestBody: request_body("Parameters", mute_request()),
265 description:
266 "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).",
267 parameters: [
268 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
269 Operation.parameter(
270 :notifications,
271 :query,
272 %Schema{allOf: [BooleanLike], default: true},
273 "Mute notifications in addition to statuses? Defaults to `true`."
274 ),
275 Operation.parameter(
276 :expires_in,
277 :query,
278 %Schema{type: :integer, default: 0},
279 "Expire the mute in `expires_in` seconds. Default 0 for infinity"
280 )
281 ],
282 responses: %{
283 200 => Operation.response("Relationship", "application/json", AccountRelationship)
284 }
285 }
286 end
287
288 def unmute_operation do
289 %Operation{
290 tags: ["Account actions"],
291 summary: "Unmute",
292 operationId: "AccountController.unmute",
293 security: [%{"oAuth" => ["follow", "write:mutes"]}],
294 description: "Unmute the given account.",
295 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
296 responses: %{
297 200 => Operation.response("Relationship", "application/json", AccountRelationship)
298 }
299 }
300 end
301
302 def block_operation do
303 %Operation{
304 tags: ["Account actions"],
305 summary: "Block",
306 operationId: "AccountController.block",
307 security: [%{"oAuth" => ["follow", "write:blocks"]}],
308 description:
309 "Block the given account. Clients should filter statuses from this account if received (e.g. due to a boost in the Home timeline)",
310 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
311 responses: %{
312 200 => Operation.response("Relationship", "application/json", AccountRelationship)
313 }
314 }
315 end
316
317 def unblock_operation do
318 %Operation{
319 tags: ["Account actions"],
320 summary: "Unblock",
321 operationId: "AccountController.unblock",
322 security: [%{"oAuth" => ["follow", "write:blocks"]}],
323 description: "Unblock the given account.",
324 parameters: [%Reference{"$ref": "#/components/parameters/accountIdOrNickname"}],
325 responses: %{
326 200 => Operation.response("Relationship", "application/json", AccountRelationship)
327 }
328 }
329 end
330
331 def note_operation do
332 %Operation{
333 tags: ["Account actions"],
334 summary: "Create note",
335 operationId: "AccountController.note",
336 security: [%{"oAuth" => ["follow", "write:accounts"]}],
337 requestBody: request_body("Parameters", note_request()),
338 description: "Create a note for the given account.",
339 parameters: [
340 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"},
341 Operation.parameter(
342 :comment,
343 :query,
344 %Schema{type: :string},
345 "Account note body"
346 )
347 ],
348 responses: %{
349 200 => Operation.response("Relationship", "application/json", AccountRelationship)
350 }
351 }
352 end
353
354 def follow_by_uri_operation do
355 %Operation{
356 tags: ["Account actions"],
357 summary: "Follow by URI",
358 operationId: "AccountController.follows",
359 security: [%{"oAuth" => ["follow", "write:follows"]}],
360 requestBody: request_body("Parameters", follow_by_uri_request(), required: true),
361 responses: %{
362 200 => Operation.response("Account", "application/json", AccountRelationship),
363 400 => Operation.response("Error", "application/json", ApiError),
364 404 => Operation.response("Error", "application/json", ApiError)
365 }
366 }
367 end
368
369 def mutes_operation do
370 %Operation{
371 tags: ["Blocks and mutes"],
372 summary: "Retrieve list of mutes",
373 operationId: "AccountController.mutes",
374 description: "Accounts the user has muted.",
375 security: [%{"oAuth" => ["follow", "read:mutes"]}],
376 parameters: [with_relationships_param() | pagination_params()],
377 responses: %{
378 200 => Operation.response("Accounts", "application/json", array_of_accounts())
379 }
380 }
381 end
382
383 def blocks_operation do
384 %Operation{
385 tags: ["Blocks and mutes"],
386 summary: "Retrieve list of blocks",
387 operationId: "AccountController.blocks",
388 description: "View your blocks. See also accounts/:id/{block,unblock}",
389 security: [%{"oAuth" => ["read:blocks"]}],
390 parameters: pagination_params(),
391 responses: %{
392 200 => Operation.response("Accounts", "application/json", array_of_accounts())
393 }
394 }
395 end
396
397 def endorsements_operation do
398 %Operation{
399 tags: ["Retrieve account information"],
400 summary: "Endorsements",
401 operationId: "AccountController.endorsements",
402 description: "Not implemented",
403 security: [%{"oAuth" => ["read:accounts"]}],
404 responses: %{
405 200 => empty_array_response()
406 }
407 }
408 end
409
410 def identity_proofs_operation do
411 %Operation{
412 tags: ["Retrieve account information"],
413 summary: "Identity proofs",
414 operationId: "AccountController.identity_proofs",
415 # Validators complains about unused path params otherwise
416 parameters: [
417 %Reference{"$ref": "#/components/parameters/accountIdOrNickname"}
418 ],
419 description: "Not implemented",
420 responses: %{
421 200 => empty_array_response()
422 }
423 }
424 end
425
426 defp create_request do
427 %Schema{
428 title: "AccountCreateRequest",
429 description: "POST body for creating an account",
430 type: :object,
431 required: [:username, :password, :agreement],
432 properties: %{
433 reason: %Schema{
434 type: :string,
435 nullable: true,
436 description:
437 "Text that will be reviewed by moderators if registrations require manual approval"
438 },
439 username: %Schema{type: :string, description: "The desired username for the account"},
440 email: %Schema{
441 type: :string,
442 nullable: true,
443 description:
444 "The email address to be used for login. Required when `account_activation_required` is enabled.",
445 format: :email
446 },
447 password: %Schema{
448 type: :string,
449 description: "The password to be used for login",
450 format: :password
451 },
452 agreement: %Schema{
453 allOf: [BooleanLike],
454 description:
455 "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."
456 },
457 locale: %Schema{
458 type: :string,
459 nullable: true,
460 description: "The language of the confirmation email that will be sent"
461 },
462 # Pleroma-specific properties:
463 fullname: %Schema{type: :string, nullable: true, description: "Full name"},
464 bio: %Schema{type: :string, description: "Bio", nullable: true, default: ""},
465 captcha_solution: %Schema{
466 type: :string,
467 nullable: true,
468 description: "Provider-specific captcha solution"
469 },
470 captcha_token: %Schema{
471 type: :string,
472 nullable: true,
473 description: "Provider-specific captcha token"
474 },
475 captcha_answer_data: %Schema{
476 type: :string,
477 nullable: true,
478 description: "Provider-specific captcha data"
479 },
480 token: %Schema{
481 type: :string,
482 nullable: true,
483 description: "Invite token required when the registrations aren't public"
484 }
485 },
486 example: %{
487 "username" => "cofe",
488 "email" => "cofe@example.com",
489 "password" => "secret",
490 "agreement" => "true",
491 "bio" => "☕️"
492 }
493 }
494 end
495
496 # Note: this is a token response (if login succeeds!), but there's no oauth operation file yet.
497 defp create_response do
498 %Schema{
499 title: "AccountCreateResponse",
500 description: "Response schema for an account",
501 type: :object,
502 properties: %{
503 # The response when auto-login on create succeeds (token is issued):
504 token_type: %Schema{type: :string},
505 access_token: %Schema{type: :string},
506 refresh_token: %Schema{type: :string},
507 scope: %Schema{type: :string},
508 created_at: %Schema{type: :integer, format: :"date-time"},
509 me: %Schema{type: :string},
510 expires_in: %Schema{type: :integer},
511 #
512 # The response when registration succeeds but auto-login fails (no token):
513 identifier: %Schema{type: :string},
514 message: %Schema{type: :string}
515 },
516 # Note: example of successful registration with failed login response:
517 # example: %{
518 # "identifier" => "missing_confirmed_email",
519 # "message" => "You have been registered. Please check your email for further instructions."
520 # },
521 example: %{
522 "token_type" => "Bearer",
523 "access_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzk",
524 "refresh_token" => "i9hAVVzGld86Pl5JtLtizKoXVvtTlSCJvwaugCxvZzz",
525 "created_at" => 1_585_918_714,
526 "expires_in" => 600,
527 "scope" => "read write follow push",
528 "me" => "https://gensokyo.2hu/users/raymoo"
529 }
530 }
531 end
532
533 defp update_credentials_request do
534 %Schema{
535 title: "AccountUpdateCredentialsRequest",
536 description: "POST body for creating an account",
537 type: :object,
538 properties: %{
539 bot: %Schema{
540 allOf: [BooleanLike],
541 nullable: true,
542 description: "Whether the account has a bot flag."
543 },
544 display_name: %Schema{
545 type: :string,
546 nullable: true,
547 description: "The display name to use for the profile."
548 },
549 note: %Schema{type: :string, description: "The account bio."},
550 avatar: %Schema{
551 type: :string,
552 nullable: true,
553 description: "Avatar image encoded using multipart/form-data",
554 format: :binary
555 },
556 header: %Schema{
557 type: :string,
558 nullable: true,
559 description: "Header image encoded using multipart/form-data",
560 format: :binary
561 },
562 locked: %Schema{
563 allOf: [BooleanLike],
564 nullable: true,
565 description: "Whether manual approval of follow requests is required."
566 },
567 accepts_chat_messages: %Schema{
568 allOf: [BooleanLike],
569 nullable: true,
570 description: "Whether the user accepts receiving chat messages."
571 },
572 fields_attributes: %Schema{
573 nullable: true,
574 oneOf: [
575 %Schema{type: :array, items: attribute_field()},
576 %Schema{type: :object, additionalProperties: attribute_field()}
577 ]
578 },
579 # NOTE: `source` field is not supported
580 #
581 # source: %Schema{
582 # type: :object,
583 # properties: %{
584 # privacy: %Schema{type: :string},
585 # sensitive: %Schema{type: :boolean},
586 # language: %Schema{type: :string}
587 # }
588 # },
589
590 # Pleroma-specific fields
591 no_rich_text: %Schema{
592 allOf: [BooleanLike],
593 nullable: true,
594 description: "html tags are stripped from all statuses requested from the API"
595 },
596 hide_followers: %Schema{
597 allOf: [BooleanLike],
598 nullable: true,
599 description: "user's followers will be hidden"
600 },
601 hide_follows: %Schema{
602 allOf: [BooleanLike],
603 nullable: true,
604 description: "user's follows will be hidden"
605 },
606 hide_followers_count: %Schema{
607 allOf: [BooleanLike],
608 nullable: true,
609 description: "user's follower count will be hidden"
610 },
611 hide_follows_count: %Schema{
612 allOf: [BooleanLike],
613 nullable: true,
614 description: "user's follow count will be hidden"
615 },
616 hide_favorites: %Schema{
617 allOf: [BooleanLike],
618 nullable: true,
619 description: "user's favorites timeline will be hidden"
620 },
621 show_role: %Schema{
622 allOf: [BooleanLike],
623 nullable: true,
624 description: "user's role (e.g admin, moderator) will be exposed to anyone in the
625 API"
626 },
627 default_scope: VisibilityScope,
628 pleroma_settings_store: %Schema{
629 type: :object,
630 nullable: true,
631 description: "Opaque user settings to be saved on the backend."
632 },
633 skip_thread_containment: %Schema{
634 allOf: [BooleanLike],
635 nullable: true,
636 description: "Skip filtering out broken threads"
637 },
638 allow_following_move: %Schema{
639 allOf: [BooleanLike],
640 nullable: true,
641 description: "Allows automatically follow moved following accounts"
642 },
643 also_known_as: %Schema{
644 type: :array,
645 items: %Schema{type: :string},
646 nullable: true,
647 description: "List of alternate ActivityPub IDs"
648 },
649 pleroma_background_image: %Schema{
650 type: :string,
651 nullable: true,
652 description: "Sets the background image of the user.",
653 format: :binary
654 },
655 discoverable: %Schema{
656 allOf: [BooleanLike],
657 nullable: true,
658 description:
659 "Discovery (listing, indexing) of this account by external services (search bots etc.) is allowed."
660 },
661 actor_type: ActorType
662 },
663 example: %{
664 bot: false,
665 display_name: "cofe",
666 note: "foobar",
667 fields_attributes: [%{name: "foo", value: "bar"}],
668 no_rich_text: false,
669 hide_followers: true,
670 hide_follows: false,
671 hide_followers_count: false,
672 hide_follows_count: false,
673 hide_favorites: false,
674 show_role: false,
675 default_scope: "private",
676 pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}},
677 skip_thread_containment: false,
678 allow_following_move: false,
679 also_known_as: ["https://foo.bar/users/foo"],
680 discoverable: false,
681 actor_type: "Person"
682 }
683 }
684 end
685
686 def array_of_accounts do
687 %Schema{
688 title: "ArrayOfAccounts",
689 type: :array,
690 items: Account,
691 example: [Account.schema().example]
692 }
693 end
694
695 defp array_of_relationships do
696 %Schema{
697 title: "ArrayOfRelationships",
698 description: "Response schema for account relationships",
699 type: :array,
700 items: AccountRelationship,
701 example: [
702 %{
703 "id" => "1",
704 "following" => true,
705 "showing_reblogs" => true,
706 "followed_by" => true,
707 "blocking" => false,
708 "blocked_by" => true,
709 "muting" => false,
710 "muting_notifications" => false,
711 "note" => "",
712 "requested" => false,
713 "domain_blocking" => false,
714 "subscribing" => false,
715 "endorsed" => true
716 },
717 %{
718 "id" => "2",
719 "following" => true,
720 "showing_reblogs" => true,
721 "followed_by" => true,
722 "blocking" => false,
723 "blocked_by" => true,
724 "muting" => true,
725 "muting_notifications" => false,
726 "note" => "",
727 "requested" => true,
728 "domain_blocking" => false,
729 "subscribing" => false,
730 "endorsed" => false
731 },
732 %{
733 "id" => "3",
734 "following" => true,
735 "showing_reblogs" => true,
736 "followed_by" => true,
737 "blocking" => true,
738 "blocked_by" => false,
739 "muting" => true,
740 "muting_notifications" => false,
741 "note" => "",
742 "requested" => false,
743 "domain_blocking" => true,
744 "subscribing" => true,
745 "endorsed" => false
746 }
747 ]
748 }
749 end
750
751 defp follow_by_uri_request do
752 %Schema{
753 title: "AccountFollowsRequest",
754 description: "POST body for muting an account",
755 type: :object,
756 properties: %{
757 uri: %Schema{type: :string, nullable: true, format: :uri}
758 },
759 required: [:uri]
760 }
761 end
762
763 defp mute_request do
764 %Schema{
765 title: "AccountMuteRequest",
766 description: "POST body for muting an account",
767 type: :object,
768 properties: %{
769 notifications: %Schema{
770 allOf: [BooleanLike],
771 nullable: true,
772 description: "Mute notifications in addition to statuses? Defaults to true.",
773 default: true
774 },
775 expires_in: %Schema{
776 type: :integer,
777 nullable: true,
778 description: "Expire the mute in `expires_in` seconds. Default 0 for infinity",
779 default: 0
780 }
781 },
782 example: %{
783 "notifications" => true,
784 "expires_in" => 86_400
785 }
786 }
787 end
788
789 defp note_request do
790 %Schema{
791 title: "AccountNoteRequest",
792 description: "POST body for adding a note for an account",
793 type: :object,
794 properties: %{
795 comment: %Schema{
796 type: :string,
797 description: "Account note body"
798 }
799 },
800 example: %{
801 "comment" => "Example note"
802 }
803 }
804 end
805
806 defp array_of_lists do
807 %Schema{
808 title: "ArrayOfLists",
809 description: "Response schema for lists",
810 type: :array,
811 items: List,
812 example: [
813 %{"id" => "123", "title" => "my list"},
814 %{"id" => "1337", "title" => "anotehr list"}
815 ]
816 }
817 end
818
819 defp array_of_statuses do
820 %Schema{
821 title: "ArrayOfStatuses",
822 type: :array,
823 items: Status
824 }
825 end
826
827 defp attribute_field do
828 %Schema{
829 title: "AccountAttributeField",
830 description: "Request schema for account custom fields",
831 type: :object,
832 properties: %{
833 name: %Schema{type: :string},
834 value: %Schema{type: :string}
835 },
836 required: [:name, :value],
837 example: %{
838 "name" => "Website",
839 "value" => "https://pleroma.com"
840 }
841 }
842 end
843 end