8922a3626db4215019723374bc7f59e97ece6ac5
[akkoma] / config / description.exs
1 use Mix.Config
2
3 websocket_config = [
4 path: "/websocket",
5 serializer: [
6 {Phoenix.Socket.V1.JSONSerializer, "~> 1.0.0"},
7 {Phoenix.Socket.V2.JSONSerializer, "~> 2.0.0"}
8 ],
9 timeout: 60_000,
10 transport_log: false,
11 compress: false
12 ]
13
14 installed_frontend_options = [
15 %{
16 key: "name",
17 label: "Name",
18 type: :string,
19 description:
20 "Name of the installed frontend. Valid config must include both `Name` and `Reference` values."
21 },
22 %{
23 key: "ref",
24 label: "Reference",
25 type: :string,
26 description:
27 "Reference of the installed frontend to be used. Valid config must include both `Name` and `Reference` values."
28 }
29 ]
30
31 frontend_options = [
32 %{
33 key: "name",
34 label: "Name",
35 type: :string,
36 description: "Name of the frontend."
37 },
38 %{
39 key: "ref",
40 label: "Reference",
41 type: :string,
42 description: "Reference of the frontend to be used."
43 },
44 %{
45 key: "git",
46 label: "Git Repository URL",
47 type: :string,
48 description: "URL of the git repository of the frontend"
49 },
50 %{
51 key: "build_url",
52 label: "Build URL",
53 type: :string,
54 description:
55 "Either an url to a zip file containing the frontend or a template to build it by inserting the `ref`. The string `${ref}` will be replaced by the configured `ref`.",
56 example: "https://some.url/builds/${ref}.zip"
57 },
58 %{
59 key: "build_dir",
60 label: "Build directory",
61 type: :string,
62 description: "The directory inside the zip file "
63 },
64 %{
65 key: "custom-http-headers",
66 label: "Custom HTTP headers",
67 type: {:list, :string},
68 description: "The custom HTTP headers for the frontend"
69 }
70 ]
71
72 config :pleroma, :config_description, [
73 %{
74 group: :pleroma,
75 key: Pleroma.Upload,
76 type: :group,
77 description: "Upload general settings",
78 children: [
79 %{
80 key: :uploader,
81 type: :module,
82 description: "Module which will be used for uploads",
83 suggestions: {:list_behaviour_implementations, Pleroma.Uploaders.Uploader}
84 },
85 %{
86 key: :filters,
87 type: {:list, :module},
88 description:
89 "List of filter modules for uploads. Module names are shortened (removed leading `Pleroma.Upload.Filter.` part), but on adding custom module you need to use full name.",
90 suggestions: {:list_behaviour_implementations, Pleroma.Upload.Filter}
91 },
92 %{
93 key: :link_name,
94 type: :boolean,
95 description:
96 "If enabled, a name parameter will be added to the URL of the upload. For example `https://instance.tld/media/imagehash.png?name=realname.png`."
97 },
98 %{
99 key: :base_url,
100 label: "Base URL",
101 type: :string,
102 description: "Base URL for the uploads, needed if you use CDN",
103 suggestions: [
104 "https://cdn-host.com"
105 ]
106 },
107 %{
108 key: :proxy_remote,
109 type: :boolean,
110 description: """
111 Proxy requests to the remote uploader.\n
112 Useful if media upload endpoint is not internet accessible.
113 """
114 },
115 %{
116 key: :filename_display_max_length,
117 type: :integer,
118 description: "Set max length of a filename to display. 0 = no limit. Default: 30"
119 }
120 ]
121 },
122 %{
123 group: :pleroma,
124 key: Pleroma.Uploaders.Local,
125 type: :group,
126 description: "Local uploader-related settings",
127 children: [
128 %{
129 key: :uploads,
130 type: :string,
131 description: "Path where user's uploads will be saved",
132 suggestions: [
133 "uploads"
134 ]
135 }
136 ]
137 },
138 %{
139 group: :pleroma,
140 key: Pleroma.Uploaders.S3,
141 type: :group,
142 description: "S3 uploader-related settings",
143 children: [
144 %{
145 key: :bucket,
146 type: :string,
147 description: "S3 bucket",
148 suggestions: [
149 "bucket"
150 ]
151 },
152 %{
153 key: :bucket_namespace,
154 type: :string,
155 description: "S3 bucket namespace",
156 suggestions: ["pleroma"]
157 },
158 %{
159 key: :truncated_namespace,
160 type: :string,
161 description:
162 "If you use S3 compatible service such as Digital Ocean Spaces or CDN, set folder name or \"\" etc." <>
163 " For example, when using CDN to S3 virtual host format, set \"\". At this time, write CNAME to CDN in Upload base_url."
164 },
165 %{
166 key: :streaming_enabled,
167 type: :boolean,
168 description:
169 "Enable streaming uploads, when enabled the file will be sent to the server in chunks as it's being read. This may be unsupported by some providers, try disabling this if you have upload problems."
170 }
171 ]
172 },
173 %{
174 group: :pleroma,
175 key: Pleroma.Upload.Filter.Mogrify,
176 type: :group,
177 description: "Uploads mogrify filter settings",
178 children: [
179 %{
180 key: :args,
181 type: [:string, {:list, :string}, {:list, :tuple}],
182 description:
183 "List of actions for the mogrify command. It's possible to add self-written settings as string. " <>
184 "For example `auto-orient, strip, {\"resize\", \"3840x1080>\"}` value will be parsed into valid list of the settings.",
185 suggestions: [
186 "strip",
187 "auto-orient",
188 {"implode", "1"}
189 ]
190 }
191 ]
192 },
193 %{
194 group: :pleroma,
195 key: Pleroma.Upload.Filter.AnonymizeFilename,
196 type: :group,
197 description: "Filter replaces the filename of the upload",
198 children: [
199 %{
200 key: :text,
201 type: :string,
202 description:
203 "Text to replace filenames in links. If no setting, {random}.extension will be used. You can get the original" <>
204 " filename extension by using {extension}, for example custom-file-name.{extension}.",
205 suggestions: [
206 "custom-file-name.{extension}"
207 ]
208 }
209 ]
210 },
211 %{
212 group: :pleroma,
213 key: Pleroma.Emails.Mailer,
214 type: :group,
215 description: "Mailer-related settings",
216 children: [
217 %{
218 key: :adapter,
219 type: :module,
220 description:
221 "One of the mail adapters listed in [Swoosh readme](https://github.com/swoosh/swoosh#adapters)",
222 suggestions: [
223 Swoosh.Adapters.SMTP,
224 Swoosh.Adapters.Sendgrid,
225 Swoosh.Adapters.Sendmail,
226 Swoosh.Adapters.Mandrill,
227 Swoosh.Adapters.Mailgun,
228 Swoosh.Adapters.Mailjet,
229 Swoosh.Adapters.Postmark,
230 Swoosh.Adapters.SparkPost,
231 Swoosh.Adapters.AmazonSES,
232 Swoosh.Adapters.Dyn,
233 Swoosh.Adapters.SocketLabs,
234 Swoosh.Adapters.Gmail
235 ]
236 },
237 %{
238 key: :enabled,
239 type: :boolean,
240 description: "Allow/disallow send emails"
241 },
242 %{
243 group: {:subgroup, Swoosh.Adapters.SMTP},
244 key: :relay,
245 type: :string,
246 description: "Hostname or IP address",
247 suggestions: ["smtp.example.com"]
248 },
249 %{
250 group: {:subgroup, Swoosh.Adapters.SMTP},
251 key: :port,
252 type: :integer,
253 description: "SMTP port"
254 },
255 %{
256 group: {:subgroup, Swoosh.Adapters.SMTP},
257 key: :username,
258 type: :string,
259 description: "SMTP auth username",
260 suggestions: ["user@example.com"]
261 },
262 %{
263 group: {:subgroup, Swoosh.Adapters.SMTP},
264 key: :password,
265 type: :string,
266 description: "SMTP auth password",
267 suggestions: ["password"]
268 },
269 %{
270 group: {:subgroup, Swoosh.Adapters.SMTP},
271 key: :ssl,
272 label: "SSL",
273 type: :boolean,
274 description: "Use implicit SSL/TLS: e.g., port 465",
275 },
276 %{
277 group: {:subgroup, Swoosh.Adapters.SMTP},
278 key: :tls,
279 label: "STARTTLS",
280 type: {:dropdown, :atom},
281 description: "Explicit TLS (STARTTLS) mode",
282 suggestions: [:if_available, :always, :never]
283 },
284 %{
285 group: {:subgroup, Swoosh.Adapters.SMTP},
286 key: :auth,
287 type: {:dropdown, :atom},
288 description: "SMTP authentication mode",
289 suggestions: [:if_available, :always, :never]
290 },
291 %{
292 group: {:subgroup, Swoosh.Adapters.SMTP},
293 key: :retries,
294 type: :integer,
295 description: "`Swoosh.Adapters.SMTP` adapter specific setting",
296 suggestions: [5]
297 },
298 %{
299 group: {:subgroup, Swoosh.Adapters.Sendgrid},
300 key: :api_key,
301 label: "API key",
302 type: :string,
303 description: "`Swoosh.Adapters.Sendgrid` adapter specific setting",
304 suggestions: ["my-api-key"]
305 },
306 %{
307 group: {:subgroup, Swoosh.Adapters.Sendmail},
308 key: :cmd_path,
309 type: :string,
310 description: "`Swoosh.Adapters.Sendmail` adapter specific setting",
311 suggestions: ["/usr/bin/sendmail"]
312 },
313 %{
314 group: {:subgroup, Swoosh.Adapters.Sendmail},
315 key: :cmd_args,
316 type: :string,
317 description: "`Swoosh.Adapters.Sendmail` adapter specific setting",
318 suggestions: ["-N delay,failure,success"]
319 },
320 %{
321 group: {:subgroup, Swoosh.Adapters.Sendmail},
322 key: :qmail,
323 type: :boolean,
324 description: "`Swoosh.Adapters.Sendmail` adapter specific setting"
325 },
326 %{
327 group: {:subgroup, Swoosh.Adapters.Mandrill},
328 key: :api_key,
329 label: "API key",
330 type: :string,
331 description: "`Swoosh.Adapters.Mandrill` adapter specific setting",
332 suggestions: ["my-api-key"]
333 },
334 %{
335 group: {:subgroup, Swoosh.Adapters.Mailgun},
336 key: :api_key,
337 label: "API key",
338 type: :string,
339 description: "`Swoosh.Adapters.Mailgun` adapter specific setting",
340 suggestions: ["my-api-key"]
341 },
342 %{
343 group: {:subgroup, Swoosh.Adapters.Mailgun},
344 key: :domain,
345 type: :string,
346 description: "`Swoosh.Adapters.Mailgun` adapter specific setting",
347 suggestions: ["pleroma.com"]
348 },
349 %{
350 group: {:subgroup, Swoosh.Adapters.Mailjet},
351 key: :api_key,
352 label: "API key",
353 type: :string,
354 description: "`Swoosh.Adapters.Mailjet` adapter specific setting",
355 suggestions: ["my-api-key"]
356 },
357 %{
358 group: {:subgroup, Swoosh.Adapters.Mailjet},
359 key: :secret,
360 type: :string,
361 description: "`Swoosh.Adapters.Mailjet` adapter specific setting",
362 suggestions: ["my-secret-key"]
363 },
364 %{
365 group: {:subgroup, Swoosh.Adapters.Postmark},
366 key: :api_key,
367 label: "API key",
368 type: :string,
369 description: "`Swoosh.Adapters.Postmark` adapter specific setting",
370 suggestions: ["my-api-key"]
371 },
372 %{
373 group: {:subgroup, Swoosh.Adapters.SparkPost},
374 key: :api_key,
375 label: "API key",
376 type: :string,
377 description: "`Swoosh.Adapters.SparkPost` adapter specific setting",
378 suggestions: ["my-api-key"]
379 },
380 %{
381 group: {:subgroup, Swoosh.Adapters.SparkPost},
382 key: :endpoint,
383 type: :string,
384 description: "`Swoosh.Adapters.SparkPost` adapter specific setting",
385 suggestions: ["https://api.sparkpost.com/api/v1"]
386 },
387 %{
388 group: {:subgroup, Swoosh.Adapters.AmazonSES},
389 key: :region,
390 type: :string,
391 description: "`Swoosh.Adapters.AmazonSES` adapter specific setting",
392 suggestions: ["us-east-1", "us-east-2"]
393 },
394 %{
395 group: {:subgroup, Swoosh.Adapters.AmazonSES},
396 key: :access_key,
397 type: :string,
398 description: "`Swoosh.Adapters.AmazonSES` adapter specific setting",
399 suggestions: ["aws-access-key"]
400 },
401 %{
402 group: {:subgroup, Swoosh.Adapters.AmazonSES},
403 key: :secret,
404 type: :string,
405 description: "`Swoosh.Adapters.AmazonSES` adapter specific setting",
406 suggestions: ["aws-secret-key"]
407 },
408 %{
409 group: {:subgroup, Swoosh.Adapters.Dyn},
410 key: :api_key,
411 label: "API key",
412 type: :string,
413 description: "`Swoosh.Adapters.Dyn` adapter specific setting",
414 suggestions: ["my-api-key"]
415 },
416 %{
417 group: {:subgroup, Swoosh.Adapters.SocketLabs},
418 key: :server_id,
419 type: :string,
420 description: "`Swoosh.Adapters.SocketLabs` adapter specific setting"
421 },
422 %{
423 group: {:subgroup, Swoosh.Adapters.SocketLabs},
424 key: :api_key,
425 label: "API key",
426 type: :string,
427 description: "`Swoosh.Adapters.SocketLabs` adapter specific setting"
428 },
429 %{
430 group: {:subgroup, Swoosh.Adapters.Gmail},
431 key: :access_token,
432 type: :string,
433 description: "`Swoosh.Adapters.Gmail` adapter specific setting"
434 }
435 ]
436 },
437 %{
438 group: :swoosh,
439 type: :group,
440 description: "`Swoosh.Adapters.Local` adapter specific settings",
441 children: [
442 %{
443 group: {:subgroup, Swoosh.Adapters.Local},
444 key: :serve_mailbox,
445 type: :boolean,
446 description: "Run the preview server together as part of your app"
447 },
448 %{
449 group: {:subgroup, Swoosh.Adapters.Local},
450 key: :preview_port,
451 type: :integer,
452 description: "The preview server port",
453 suggestions: [4001]
454 }
455 ]
456 },
457 %{
458 group: :pleroma,
459 key: :uri_schemes,
460 label: "URI Schemes",
461 type: :group,
462 description: "URI schemes related settings",
463 children: [
464 %{
465 key: :valid_schemes,
466 type: {:list, :string},
467 description: "List of the scheme part that is considered valid to be an URL",
468 suggestions: [
469 "https",
470 "http",
471 "dat",
472 "dweb",
473 "gopher",
474 "hyper",
475 "ipfs",
476 "ipns",
477 "irc",
478 "ircs",
479 "magnet",
480 "mailto",
481 "mumble",
482 "ssb",
483 "xmpp"
484 ]
485 }
486 ]
487 },
488 %{
489 group: :pleroma,
490 key: :instance,
491 type: :group,
492 description: "Instance-related settings",
493 children: [
494 %{
495 key: :name,
496 type: :string,
497 description: "Name of the instance",
498 suggestions: [
499 "Pleroma"
500 ]
501 },
502 %{
503 key: :email,
504 label: "Admin Email Address",
505 type: :string,
506 description: "Email used to reach an Administrator/Moderator of the instance",
507 suggestions: [
508 "email@example.com"
509 ]
510 },
511 %{
512 key: :notify_email,
513 label: "Sender Email Address",
514 type: :string,
515 description: "Envelope FROM address for mail sent via Pleroma",
516 suggestions: [
517 "notify@example.com"
518 ]
519 },
520 %{
521 key: :description,
522 type: :string,
523 description:
524 "The instance's description. It can be seen in nodeinfo and `/api/v1/instance`",
525 suggestions: [
526 "Very cool instance"
527 ]
528 },
529 %{
530 key: :limit,
531 type: :integer,
532 description: "Posts character limit (CW/Subject included in the counter)",
533 suggestions: [
534 5_000
535 ]
536 },
537 %{
538 key: :chat_limit,
539 type: :integer,
540 description: "Character limit of the instance chat messages",
541 suggestions: [
542 5_000
543 ]
544 },
545 %{
546 key: :remote_limit,
547 type: :integer,
548 description: "Hard character limit beyond which remote posts will be dropped",
549 suggestions: [
550 100_000
551 ]
552 },
553 %{
554 key: :upload_limit,
555 type: :integer,
556 description: "File size limit of uploads (except for avatar, background, banner)",
557 suggestions: [
558 16_000_000
559 ]
560 },
561 %{
562 key: :avatar_upload_limit,
563 type: :integer,
564 description: "File size limit of user's profile avatars",
565 suggestions: [
566 2_000_000
567 ]
568 },
569 %{
570 key: :background_upload_limit,
571 type: :integer,
572 description: "File size limit of user's profile backgrounds",
573 suggestions: [
574 4_000_000
575 ]
576 },
577 %{
578 key: :banner_upload_limit,
579 type: :integer,
580 description: "File size limit of user's profile banners",
581 suggestions: [
582 4_000_000
583 ]
584 },
585 %{
586 key: :poll_limits,
587 type: :map,
588 description: "A map with poll limits for local polls",
589 suggestions: [
590 %{
591 max_options: 20,
592 max_option_chars: 200,
593 min_expiration: 0,
594 max_expiration: 31_536_000
595 }
596 ],
597 children: [
598 %{
599 key: :max_options,
600 type: :integer,
601 description: "Maximum number of options",
602 suggestions: [20]
603 },
604 %{
605 key: :max_option_chars,
606 type: :integer,
607 description: "Maximum number of characters per option",
608 suggestions: [200]
609 },
610 %{
611 key: :min_expiration,
612 type: :integer,
613 description: "Minimum expiration time (in seconds)",
614 suggestions: [0]
615 },
616 %{
617 key: :max_expiration,
618 type: :integer,
619 description: "Maximum expiration time (in seconds)",
620 suggestions: [3600]
621 }
622 ]
623 },
624 %{
625 key: :registrations_open,
626 type: :boolean,
627 description:
628 "Enable registrations for anyone. Invitations require this setting to be disabled."
629 },
630 %{
631 key: :invites_enabled,
632 type: :boolean,
633 description:
634 "Enable user invitations for admins (depends on `registrations_open` being disabled)"
635 },
636 %{
637 key: :account_activation_required,
638 type: :boolean,
639 description: "Require users to confirm their emails before signing in"
640 },
641 %{
642 key: :account_approval_required,
643 type: :boolean,
644 description: "Require users to be manually approved by an admin before signing in"
645 },
646 %{
647 key: :federating,
648 type: :boolean,
649 description: "Enable federation with other instances"
650 },
651 %{
652 key: :federation_incoming_replies_max_depth,
653 label: "Fed. incoming replies max depth",
654 type: :integer,
655 description:
656 "Max. depth of reply-to and reply activities fetching on incoming federation, to prevent out-of-memory situations while" <>
657 " fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes.",
658 suggestions: [
659 100
660 ]
661 },
662 %{
663 key: :federation_reachability_timeout_days,
664 label: "Fed. reachability timeout days",
665 type: :integer,
666 description:
667 "Timeout (in days) of each external federation target being unreachable prior to pausing federating to it",
668 suggestions: [
669 7
670 ]
671 },
672 %{
673 key: :allow_relay,
674 type: :boolean,
675 description: "Enable Pleroma's Relay, which makes it possible to follow a whole instance"
676 },
677 %{
678 key: :public,
679 type: :boolean,
680 description:
681 "Makes the client API in authenticated mode-only except for user-profiles." <>
682 " Useful for disabling the Local Timeline and The Whole Known Network. " <>
683 " Note: when setting to `false`, please also check `:restrict_unauthenticated` setting."
684 },
685 %{
686 key: :quarantined_instances,
687 type: {:list, :string},
688 description:
689 "List of ActivityPub instances where private (DMs, followers-only) activities will not be sent",
690 suggestions: [
691 "quarantined.com",
692 "*.quarantined.com"
693 ]
694 },
695 %{
696 key: :static_dir,
697 type: :string,
698 description: "Instance static directory",
699 suggestions: [
700 "instance/static/"
701 ]
702 },
703 %{
704 key: :allowed_post_formats,
705 type: {:list, :string},
706 description: "MIME-type list of formats allowed to be posted (transformed into HTML)",
707 suggestions: [
708 "text/plain",
709 "text/html",
710 "text/markdown",
711 "text/bbcode"
712 ]
713 },
714 %{
715 key: :extended_nickname_format,
716 type: :boolean,
717 description:
718 "Enable to use extended local nicknames format (allows underscores/dashes)." <>
719 " This will break federation with older software for theses nicknames."
720 },
721 %{
722 key: :cleanup_attachments,
723 type: :boolean,
724 description: """
725 Enable to remove associated attachments when status is removed.
726 This will not affect duplicates and attachments without status.
727 Enabling this will increase load to database when deleting statuses on larger instances.
728 """
729 },
730 %{
731 key: :max_pinned_statuses,
732 type: :integer,
733 description: "The maximum number of pinned statuses. 0 will disable the feature.",
734 suggestions: [
735 0,
736 1,
737 3
738 ]
739 },
740 %{
741 key: :autofollowed_nicknames,
742 type: {:list, :string},
743 description:
744 "Set to nicknames of (local) users that every new user should automatically follow"
745 },
746 %{
747 key: :autofollowing_nicknames,
748 type: {:list, :string},
749 description:
750 "Set to nicknames of (local) users that automatically follows every newly registered user"
751 },
752 %{
753 key: :attachment_links,
754 type: :boolean,
755 description: "Enable to automatically add attachment link text to statuses"
756 },
757 %{
758 key: :max_report_comment_size,
759 type: :integer,
760 description: "The maximum size of the report comment. Default: 1000.",
761 suggestions: [
762 1_000
763 ]
764 },
765 %{
766 key: :safe_dm_mentions,
767 label: "Safe DM mentions",
768 type: :boolean,
769 description:
770 "If enabled, only mentions at the beginning of a post will be used to address people in direct messages." <>
771 " This is to prevent accidental mentioning of people when talking about them (e.g. \"@admin please keep an eye on @bad_actor\")." <>
772 " Default: disabled"
773 },
774 %{
775 key: :healthcheck,
776 type: :boolean,
777 description: "If enabled, system data will be shown on `/api/pleroma/healthcheck`"
778 },
779 %{
780 key: :remote_post_retention_days,
781 type: :integer,
782 description:
783 "The default amount of days to retain remote posts when pruning the database",
784 suggestions: [
785 90
786 ]
787 },
788 %{
789 key: :user_bio_length,
790 type: :integer,
791 description: "A user bio maximum length. Default: 5000.",
792 suggestions: [
793 5_000
794 ]
795 },
796 %{
797 key: :user_name_length,
798 type: :integer,
799 description: "A user name maximum length. Default: 100.",
800 suggestions: [
801 100
802 ]
803 },
804 %{
805 key: :skip_thread_containment,
806 type: :boolean,
807 description: "Skip filtering out broken threads. Default: enabled."
808 },
809 %{
810 key: :limit_to_local_content,
811 type: {:dropdown, :atom},
812 description:
813 "Limit unauthenticated users to search for local statutes and users only. Default: `:unauthenticated`.",
814 suggestions: [
815 :unauthenticated,
816 :all,
817 false
818 ]
819 },
820 %{
821 key: :max_account_fields,
822 type: :integer,
823 description: "The maximum number of custom fields in the user profile. Default: 10.",
824 suggestions: [
825 10
826 ]
827 },
828 %{
829 key: :max_remote_account_fields,
830 type: :integer,
831 description:
832 "The maximum number of custom fields in the remote user profile. Default: 20.",
833 suggestions: [
834 20
835 ]
836 },
837 %{
838 key: :account_field_name_length,
839 type: :integer,
840 description: "An account field name maximum length. Default: 512.",
841 suggestions: [
842 512
843 ]
844 },
845 %{
846 key: :account_field_value_length,
847 type: :integer,
848 description: "An account field value maximum length. Default: 2048.",
849 suggestions: [
850 2048
851 ]
852 },
853 %{
854 key: :registration_reason_length,
855 type: :integer,
856 description: "Maximum registration reason length. Default: 500.",
857 suggestions: [
858 500
859 ]
860 },
861 %{
862 key: :external_user_synchronization,
863 type: :boolean,
864 description: "Enabling following/followers counters synchronization for external users"
865 },
866 %{
867 key: :multi_factor_authentication,
868 type: :keyword,
869 description: "Multi-factor authentication settings",
870 suggestions: [
871 [
872 totp: [digits: 6, period: 30],
873 backup_codes: [number: 5, length: 16]
874 ]
875 ],
876 children: [
877 %{
878 key: :totp,
879 label: "TOTP settings",
880 type: :keyword,
881 description: "TOTP settings",
882 suggestions: [digits: 6, period: 30],
883 children: [
884 %{
885 key: :digits,
886 type: :integer,
887 suggestions: [6],
888 description:
889 "Determines the length of a one-time pass-code, in characters. Defaults to 6 characters."
890 },
891 %{
892 key: :period,
893 type: :integer,
894 suggestions: [30],
895 description:
896 "A period for which the TOTP code will be valid, in seconds. Defaults to 30 seconds."
897 }
898 ]
899 },
900 %{
901 key: :backup_codes,
902 type: :keyword,
903 description: "MFA backup codes settings",
904 suggestions: [number: 5, length: 16],
905 children: [
906 %{
907 key: :number,
908 type: :integer,
909 suggestions: [5],
910 description: "Number of backup codes to generate."
911 },
912 %{
913 key: :length,
914 type: :integer,
915 suggestions: [16],
916 description:
917 "Determines the length of backup one-time pass-codes, in characters. Defaults to 16 characters."
918 }
919 ]
920 }
921 ]
922 },
923 %{
924 key: :instance_thumbnail,
925 type: {:string, :image},
926 description:
927 "The instance thumbnail can be any image that represents your instance and is used by some apps or services when they display information about your instance.",
928 suggestions: ["/instance/thumbnail.jpeg"]
929 },
930 %{
931 key: :show_reactions,
932 type: :boolean,
933 description: "Let favourites and emoji reactions be viewed through the API."
934 }
935 ]
936 },
937 %{
938 group: :pleroma,
939 key: :welcome,
940 type: :group,
941 description: "Welcome messages settings",
942 children: [
943 %{
944 key: :direct_message,
945 type: :keyword,
946 descpiption: "Direct message settings",
947 children: [
948 %{
949 key: :enabled,
950 type: :boolean,
951 description: "Enables sending a direct message to newly registered users"
952 },
953 %{
954 key: :message,
955 type: :string,
956 description: "A message that will be sent to newly registered users",
957 suggestions: [
958 "Hi, @username! Welcome on board!"
959 ]
960 },
961 %{
962 key: :sender_nickname,
963 type: :string,
964 description: "The nickname of the local user that sends a welcome message",
965 suggestions: [
966 "lain"
967 ]
968 }
969 ]
970 },
971 %{
972 key: :chat_message,
973 type: :keyword,
974 descpiption: "Chat message settings",
975 children: [
976 %{
977 key: :enabled,
978 type: :boolean,
979 description: "Enables sending a chat message to newly registered users"
980 },
981 %{
982 key: :message,
983 type: :string,
984 description:
985 "A message that will be sent to newly registered users as a chat message",
986 suggestions: [
987 "Hello, welcome on board!"
988 ]
989 },
990 %{
991 key: :sender_nickname,
992 type: :string,
993 description: "The nickname of the local user that sends a welcome chat message",
994 suggestions: [
995 "lain"
996 ]
997 }
998 ]
999 },
1000 %{
1001 key: :email,
1002 type: :keyword,
1003 descpiption: "Email message settings",
1004 children: [
1005 %{
1006 key: :enabled,
1007 type: :boolean,
1008 description: "Enables sending an email to newly registered users"
1009 },
1010 %{
1011 key: :sender,
1012 type: [:string, :tuple],
1013 description:
1014 "Email address and/or nickname that will be used to send the welcome email.",
1015 suggestions: [
1016 {"Pleroma App", "welcome@pleroma.app"}
1017 ]
1018 },
1019 %{
1020 key: :subject,
1021 type: :string,
1022 description:
1023 "Subject of the welcome email. EEX template with user and instance_name variables can be used.",
1024 suggestions: ["Welcome to <%= instance_name%>"]
1025 },
1026 %{
1027 key: :html,
1028 type: :string,
1029 description:
1030 "HTML content of the welcome email. EEX template with user and instance_name variables can be used.",
1031 suggestions: ["<h1>Hello <%= user.name%>. Welcome to <%= instance_name%></h1>"]
1032 },
1033 %{
1034 key: :text,
1035 type: :string,
1036 description:
1037 "Text content of the welcome email. EEX template with user and instance_name variables can be used.",
1038 suggestions: ["Hello <%= user.name%>. \n Welcome to <%= instance_name%>\n"]
1039 }
1040 ]
1041 }
1042 ]
1043 },
1044 %{
1045 group: :logger,
1046 type: :group,
1047 description: "Logger-related settings",
1048 children: [
1049 %{
1050 key: :backends,
1051 type: [:atom, :tuple, :module],
1052 description:
1053 "Where logs will be sent, :console - send logs to stdout, { ExSyslogger, :ex_syslogger } - to syslog, Quack.Logger - to Slack.",
1054 suggestions: [:console, {ExSyslogger, :ex_syslogger}, Quack.Logger]
1055 }
1056 ]
1057 },
1058 %{
1059 group: :logger,
1060 type: :group,
1061 key: :ex_syslogger,
1062 label: "ExSyslogger",
1063 description: "ExSyslogger-related settings",
1064 children: [
1065 %{
1066 key: :level,
1067 type: {:dropdown, :atom},
1068 description: "Log level",
1069 suggestions: [:debug, :info, :warn, :error]
1070 },
1071 %{
1072 key: :ident,
1073 type: :string,
1074 description:
1075 "A string that's prepended to every message, and is typically set to the app name",
1076 suggestions: ["pleroma"]
1077 },
1078 %{
1079 key: :format,
1080 type: :string,
1081 description: "Default: \"$date $time [$level] $levelpad$node $metadata $message\"",
1082 suggestions: ["$metadata[$level] $message"]
1083 },
1084 %{
1085 key: :metadata,
1086 type: {:list, :atom},
1087 suggestions: [:request_id]
1088 }
1089 ]
1090 },
1091 %{
1092 group: :logger,
1093 type: :group,
1094 key: :console,
1095 label: "Console Logger",
1096 description: "Console logger settings",
1097 children: [
1098 %{
1099 key: :level,
1100 type: {:dropdown, :atom},
1101 description: "Log level",
1102 suggestions: [:debug, :info, :warn, :error]
1103 },
1104 %{
1105 key: :format,
1106 type: :string,
1107 description: "Default: \"$date $time [$level] $levelpad$node $metadata $message\"",
1108 suggestions: ["$metadata[$level] $message"]
1109 },
1110 %{
1111 key: :metadata,
1112 type: {:list, :atom},
1113 suggestions: [:request_id]
1114 }
1115 ]
1116 },
1117 %{
1118 group: :quack,
1119 type: :group,
1120 label: "Quack Logger",
1121 description: "Quack-related settings",
1122 children: [
1123 %{
1124 key: :level,
1125 type: {:dropdown, :atom},
1126 description: "Log level",
1127 suggestions: [:debug, :info, :warn, :error]
1128 },
1129 %{
1130 key: :meta,
1131 type: {:list, :atom},
1132 description: "Configure which metadata you want to report on",
1133 suggestions: [
1134 :application,
1135 :module,
1136 :file,
1137 :function,
1138 :line,
1139 :pid,
1140 :crash_reason,
1141 :initial_call,
1142 :registered_name,
1143 :all,
1144 :none
1145 ]
1146 },
1147 %{
1148 key: :webhook_url,
1149 label: "Webhook URL",
1150 type: :string,
1151 description: "Configure the Slack incoming webhook",
1152 suggestions: ["https://hooks.slack.com/services/YOUR-KEY-HERE"]
1153 }
1154 ]
1155 },
1156 %{
1157 group: :pleroma,
1158 key: :frontend_configurations,
1159 type: :group,
1160 description:
1161 "This form can be used to configure a keyword list that keeps the configuration data for any " <>
1162 "kind of frontend. By default, settings for pleroma_fe and masto_fe are configured. If you want to " <>
1163 "add your own configuration your settings all fields must be complete.",
1164 children: [
1165 %{
1166 key: :pleroma_fe,
1167 label: "Pleroma FE",
1168 type: :map,
1169 description: "Settings for Pleroma FE",
1170 suggestions: [
1171 %{
1172 alwaysShowSubjectInput: true,
1173 background: "/static/aurora_borealis.jpg",
1174 collapseMessageWithSubject: false,
1175 disableChat: false,
1176 greentext: false,
1177 hideFilteredStatuses: false,
1178 hideMutedPosts: false,
1179 hidePostStats: false,
1180 hideSitename: false,
1181 hideUserStats: false,
1182 loginMethod: "password",
1183 logo: "/static/logo.svg",
1184 logoMargin: ".1em",
1185 logoMask: true,
1186 minimalScopesMode: false,
1187 noAttachmentLinks: false,
1188 nsfwCensorImage: "/static/img/nsfw.74818f9.png",
1189 postContentType: "text/plain",
1190 redirectRootLogin: "/main/friends",
1191 redirectRootNoLogin: "/main/all",
1192 scopeCopy: true,
1193 sidebarRight: false,
1194 showFeaturesPanel: true,
1195 showInstanceSpecificPanel: false,
1196 subjectLineBehavior: "email",
1197 theme: "pleroma-dark",
1198 webPushNotifications: false
1199 }
1200 ],
1201 children: [
1202 %{
1203 key: :alwaysShowSubjectInput,
1204 label: "Always show subject input",
1205 type: :boolean,
1206 description: "When disabled, auto-hide the subject field if it's empty"
1207 },
1208 %{
1209 key: :background,
1210 type: {:string, :image},
1211 description:
1212 "URL of the background, unless viewing a user profile with a background that is set",
1213 suggestions: ["/images/city.jpg"]
1214 },
1215 %{
1216 key: :collapseMessageWithSubject,
1217 label: "Collapse message with subject",
1218 type: :boolean,
1219 description:
1220 "When a message has a subject (aka Content Warning), collapse it by default"
1221 },
1222 %{
1223 key: :disableChat,
1224 label: "PleromaFE Chat",
1225 type: :boolean,
1226 description: "Disables PleromaFE Chat component"
1227 },
1228 %{
1229 key: :greentext,
1230 label: "Greentext",
1231 type: :boolean,
1232 description: "Enables green text on lines prefixed with the > character"
1233 },
1234 %{
1235 key: :hideFilteredStatuses,
1236 label: "Hide Filtered Statuses",
1237 type: :boolean,
1238 description: "Hides filtered statuses from timelines"
1239 },
1240 %{
1241 key: :hideMutedPosts,
1242 label: "Hide Muted Posts",
1243 type: :boolean,
1244 description: "Hides muted statuses from timelines"
1245 },
1246 %{
1247 key: :hidePostStats,
1248 label: "Hide post stats",
1249 type: :boolean,
1250 description: "Hide notices statistics (repeats, favorites, ...)"
1251 },
1252 %{
1253 key: :hideSitename,
1254 label: "Hide Sitename",
1255 type: :boolean,
1256 description: "Hides instance name from PleromaFE banner"
1257 },
1258 %{
1259 key: :hideUserStats,
1260 label: "Hide user stats",
1261 type: :boolean,
1262 description:
1263 "Hide profile statistics (posts, posts per day, followers, followings, ...)"
1264 },
1265 %{
1266 key: :logo,
1267 type: {:string, :image},
1268 description: "URL of the logo, defaults to Pleroma's logo",
1269 suggestions: ["/static/logo.svg"]
1270 },
1271 %{
1272 key: :logoMargin,
1273 label: "Logo margin",
1274 type: :string,
1275 description:
1276 "Allows you to adjust vertical margins between logo boundary and navbar borders. " <>
1277 "The idea is that to have logo's image without any extra margins and instead adjust them to your need in layout.",
1278 suggestions: [".1em"]
1279 },
1280 %{
1281 key: :logoMask,
1282 label: "Logo mask",
1283 type: :boolean,
1284 description:
1285 "By default it assumes logo used will be monochrome with alpha channel to be compatible with both light and dark themes. " <>
1286 "If you want a colorful logo you must disable logoMask."
1287 },
1288 %{
1289 key: :minimalScopesMode,
1290 label: "Minimal scopes mode",
1291 type: :boolean,
1292 description:
1293 "Limit scope selection to Direct, User default, and Scope of post replying to. " <>
1294 "Also prevents replying to a DM with a public post from PleromaFE."
1295 },
1296 %{
1297 key: :nsfwCensorImage,
1298 label: "NSFW Censor Image",
1299 type: {:string, :image},
1300 description:
1301 "URL of the image to use for hiding NSFW media attachments in the timeline",
1302 suggestions: ["/static/img/nsfw.74818f9.png"]
1303 },
1304 %{
1305 key: :postContentType,
1306 label: "Post Content Type",
1307 type: {:dropdown, :atom},
1308 description: "Default post formatting option",
1309 suggestions: ["text/plain", "text/html", "text/markdown", "text/bbcode"]
1310 },
1311 %{
1312 key: :redirectRootNoLogin,
1313 label: "Redirect root no login",
1314 type: :string,
1315 description:
1316 "Relative URL which indicates where to redirect when a user isn't logged in",
1317 suggestions: ["/main/all"]
1318 },
1319 %{
1320 key: :redirectRootLogin,
1321 label: "Redirect root login",
1322 type: :string,
1323 description:
1324 "Relative URL which indicates where to redirect when a user is logged in",
1325 suggestions: ["/main/friends"]
1326 },
1327 %{
1328 key: :scopeCopy,
1329 label: "Scope copy",
1330 type: :boolean,
1331 description: "Copy the scope (private/unlisted/public) in replies to posts by default"
1332 },
1333 %{
1334 key: :sidebarRight,
1335 label: "Sidebar on Right",
1336 type: :boolean,
1337 description: "Change alignment of sidebar and panels to the right"
1338 },
1339 %{
1340 key: :showFeaturesPanel,
1341 label: "Show instance features panel",
1342 type: :boolean,
1343 description:
1344 "Enables panel displaying functionality of the instance on the About page"
1345 },
1346 %{
1347 key: :showInstanceSpecificPanel,
1348 label: "Show instance specific panel",
1349 type: :boolean,
1350 description: "Whether to show the instance's custom panel"
1351 },
1352 %{
1353 key: :subjectLineBehavior,
1354 label: "Subject line behavior",
1355 type: :string,
1356 description: "Allows changing the default behaviour of subject lines in replies.
1357 `email`: copy and preprend re:, as in email,
1358 `masto`: copy verbatim, as in Mastodon,
1359 `noop`: don't copy the subject.",
1360 suggestions: ["email", "masto", "noop"]
1361 },
1362 %{
1363 key: :theme,
1364 type: :string,
1365 description: "Which theme to use. Available themes are defined in styles.json",
1366 suggestions: ["pleroma-dark"]
1367 }
1368 ]
1369 },
1370 %{
1371 key: :masto_fe,
1372 label: "Masto FE",
1373 type: :map,
1374 description: "Settings for Masto FE",
1375 suggestions: [
1376 %{
1377 showInstanceSpecificPanel: true
1378 }
1379 ],
1380 children: [
1381 %{
1382 key: :showInstanceSpecificPanel,
1383 label: "Show instance specific panel",
1384 type: :boolean,
1385 description: "Whenether to show the instance's specific panel"
1386 }
1387 ]
1388 }
1389 ]
1390 },
1391 %{
1392 group: :pleroma,
1393 key: :assets,
1394 type: :group,
1395 description:
1396 "This section configures assets to be used with various frontends. Currently the only option relates to mascots on the mastodon frontend",
1397 children: [
1398 %{
1399 key: :mascots,
1400 type: {:keyword, :map},
1401 description:
1402 "Keyword of mascots, each element must contain both an URL and a mime_type key",
1403 suggestions: [
1404 pleroma_fox_tan: %{
1405 url: "/images/pleroma-fox-tan-smol.png",
1406 mime_type: "image/png"
1407 },
1408 pleroma_fox_tan_shy: %{
1409 url: "/images/pleroma-fox-tan-shy.png",
1410 mime_type: "image/png"
1411 }
1412 ]
1413 },
1414 %{
1415 key: :default_mascot,
1416 type: :atom,
1417 description:
1418 "This will be used as the default mascot on MastoFE. Default: `:pleroma_fox_tan`",
1419 suggestions: [
1420 :pleroma_fox_tan
1421 ]
1422 },
1423 %{
1424 key: :default_user_avatar,
1425 type: {:string, :image},
1426 description: "URL of the default user avatar",
1427 suggestions: ["/images/avi.png"]
1428 }
1429 ]
1430 },
1431 %{
1432 group: :pleroma,
1433 key: :manifest,
1434 type: :group,
1435 description:
1436 "This section describe PWA manifest instance-specific values. Currently this option relate only for MastoFE.",
1437 children: [
1438 %{
1439 key: :icons,
1440 type: {:list, :map},
1441 description: "Describe the icons of the app",
1442 suggestion: [
1443 %{
1444 src: "/static/logo.png"
1445 },
1446 %{
1447 src: "/static/icon.png",
1448 type: "image/png"
1449 },
1450 %{
1451 src: "/static/icon.ico",
1452 sizes: "72x72 96x96 128x128 256x256"
1453 }
1454 ]
1455 },
1456 %{
1457 key: :theme_color,
1458 type: :string,
1459 description: "Describe the theme color of the app",
1460 suggestions: ["#282c37", "mediumpurple"]
1461 },
1462 %{
1463 key: :background_color,
1464 type: :string,
1465 description: "Describe the background color of the app",
1466 suggestions: ["#191b22", "aliceblue"]
1467 }
1468 ]
1469 },
1470 %{
1471 group: :pleroma,
1472 key: :media_proxy,
1473 type: :group,
1474 description: "Media proxy",
1475 children: [
1476 %{
1477 key: :enabled,
1478 type: :boolean,
1479 description: "Enables proxying of remote media via the instance's proxy"
1480 },
1481 %{
1482 key: :base_url,
1483 label: "Base URL",
1484 type: :string,
1485 description:
1486 "The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.",
1487 suggestions: ["https://example.com"]
1488 },
1489 %{
1490 key: :invalidation,
1491 type: :keyword,
1492 descpiption: "",
1493 suggestions: [
1494 enabled: true,
1495 provider: Pleroma.Web.MediaProxy.Invalidation.Script
1496 ],
1497 children: [
1498 %{
1499 key: :enabled,
1500 type: :boolean,
1501 description: "Enables media cache object invalidation."
1502 },
1503 %{
1504 key: :provider,
1505 type: :module,
1506 description: "Module which will be used to purge objects from the cache.",
1507 suggestions: [
1508 Pleroma.Web.MediaProxy.Invalidation.Script,
1509 Pleroma.Web.MediaProxy.Invalidation.Http
1510 ]
1511 }
1512 ]
1513 },
1514 %{
1515 key: :proxy_opts,
1516 label: "Advanced MediaProxy Options",
1517 type: :keyword,
1518 description: "Internal Pleroma.ReverseProxy settings",
1519 suggestions: [
1520 redirect_on_failure: false,
1521 max_body_length: 25 * 1_048_576,
1522 max_read_duration: 30_000
1523 ],
1524 children: [
1525 %{
1526 key: :redirect_on_failure,
1527 type: :boolean,
1528 description: """
1529 Redirects the client to the origin server upon encountering HTTP errors.\n
1530 Note that files larger than Max Body Length will trigger an error. (e.g., Peertube videos)\n\n
1531 **WARNING:** This setting will allow larger files to be accessed, but exposes the\n
1532 IP addresses of your users to the other servers, bypassing the MediaProxy.
1533 """
1534 },
1535 %{
1536 key: :max_body_length,
1537 type: :integer,
1538 description: "Maximum file size allowed through the Pleroma MediaProxy cache."
1539 },
1540 %{
1541 key: :max_read_duration,
1542 type: :integer,
1543 description: "Timeout (in milliseconds) of GET request to the remote URI."
1544 }
1545 ]
1546 },
1547 %{
1548 key: :whitelist,
1549 type: {:list, :string},
1550 description: "List of hosts with scheme to bypass the MediaProxy",
1551 suggestions: ["http://example.com"]
1552 }
1553 ]
1554 },
1555 %{
1556 group: :pleroma,
1557 key: :media_preview_proxy,
1558 type: :group,
1559 description: "Media preview proxy",
1560 children: [
1561 %{
1562 key: :enabled,
1563 type: :boolean,
1564 description:
1565 "Enables proxying of remote media preview to the instance's proxy. Requires enabled media proxy."
1566 },
1567 %{
1568 key: :thumbnail_max_width,
1569 type: :integer,
1570 description:
1571 "Max width of preview thumbnail for images (video preview always has original dimensions)."
1572 },
1573 %{
1574 key: :thumbnail_max_height,
1575 type: :integer,
1576 description:
1577 "Max height of preview thumbnail for images (video preview always has original dimensions)."
1578 },
1579 %{
1580 key: :image_quality,
1581 type: :integer,
1582 description: "Quality of the output. Ranges from 0 (min quality) to 100 (max quality)."
1583 },
1584 %{
1585 key: :min_content_length,
1586 type: :integer,
1587 description:
1588 "Min content length to perform preview, in bytes. If greater than 0, media smaller in size will be served as is, without thumbnailing."
1589 }
1590 ]
1591 },
1592 %{
1593 group: :pleroma,
1594 key: Pleroma.Web.MediaProxy.Invalidation.Http,
1595 type: :group,
1596 description: "HTTP invalidate settings",
1597 children: [
1598 %{
1599 key: :method,
1600 type: :atom,
1601 description: "HTTP method of request. Default: :purge"
1602 },
1603 %{
1604 key: :headers,
1605 type: {:keyword, :string},
1606 description: "HTTP headers of request",
1607 suggestions: [{"x-refresh", 1}]
1608 },
1609 %{
1610 key: :options,
1611 type: :keyword,
1612 description: "Request options",
1613 children: [
1614 %{
1615 key: :params,
1616 type: {:map, :string}
1617 }
1618 ]
1619 }
1620 ]
1621 },
1622 %{
1623 group: :pleroma,
1624 key: Pleroma.Web.MediaProxy.Invalidation.Script,
1625 type: :group,
1626 description: "Invalidation script settings",
1627 children: [
1628 %{
1629 key: :script_path,
1630 type: :string,
1631 description: "Path to executable script which will purge cached items.",
1632 suggestions: ["./installation/nginx-cache-purge.sh.example"]
1633 },
1634 %{
1635 key: :url_format,
1636 type: :string,
1637 description:
1638 "Optional URL format preprocessing. Only required for Apache's htcacheclean.",
1639 suggestions: [":htcacheclean"]
1640 }
1641 ]
1642 },
1643 %{
1644 group: :pleroma,
1645 key: :gopher,
1646 type: :group,
1647 description: "Gopher settings",
1648 children: [
1649 %{
1650 key: :enabled,
1651 type: :boolean,
1652 description: "Enables the gopher interface"
1653 },
1654 %{
1655 key: :ip,
1656 label: "IP",
1657 type: :tuple,
1658 description: "IP address to bind to",
1659 suggestions: [{0, 0, 0, 0}]
1660 },
1661 %{
1662 key: :port,
1663 type: :integer,
1664 description: "Port to bind to",
1665 suggestions: [9999]
1666 },
1667 %{
1668 key: :dstport,
1669 type: :integer,
1670 description: "Port advertised in URLs (optional, defaults to port)",
1671 suggestions: [9999]
1672 }
1673 ]
1674 },
1675 %{
1676 group: :pleroma,
1677 key: :activitypub,
1678 label: "ActivityPub",
1679 type: :group,
1680 description: "ActivityPub-related settings",
1681 children: [
1682 %{
1683 key: :unfollow_blocked,
1684 type: :boolean,
1685 description: "Whether blocks result in people getting unfollowed"
1686 },
1687 %{
1688 key: :outgoing_blocks,
1689 type: :boolean,
1690 description: "Whether to federate blocks to other instances"
1691 },
1692 %{
1693 key: :sign_object_fetches,
1694 type: :boolean,
1695 description: "Sign object fetches with HTTP signatures"
1696 },
1697 %{
1698 key: :note_replies_output_limit,
1699 type: :integer,
1700 description:
1701 "The number of Note replies' URIs to be included with outgoing federation (`5` to match Mastodon hardcoded value, `0` to disable the output)"
1702 },
1703 %{
1704 key: :follow_handshake_timeout,
1705 type: :integer,
1706 description: "Following handshake timeout",
1707 suggestions: [500]
1708 }
1709 ]
1710 },
1711 %{
1712 group: :pleroma,
1713 key: :http_security,
1714 label: "HTTP security",
1715 type: :group,
1716 description: "HTTP security settings",
1717 children: [
1718 %{
1719 key: :enabled,
1720 type: :boolean,
1721 description: "Whether the managed content security policy is enabled"
1722 },
1723 %{
1724 key: :sts,
1725 label: "STS",
1726 type: :boolean,
1727 description: "Whether to additionally send a Strict-Transport-Security header"
1728 },
1729 %{
1730 key: :sts_max_age,
1731 label: "STS max age",
1732 type: :integer,
1733 description: "The maximum age for the Strict-Transport-Security header if sent",
1734 suggestions: [31_536_000]
1735 },
1736 %{
1737 key: :ct_max_age,
1738 label: "CT max age",
1739 type: :integer,
1740 description: "The maximum age for the Expect-CT header if sent",
1741 suggestions: [2_592_000]
1742 },
1743 %{
1744 key: :referrer_policy,
1745 type: :string,
1746 description: "The referrer policy to use, either \"same-origin\" or \"no-referrer\"",
1747 suggestions: ["same-origin", "no-referrer"]
1748 },
1749 %{
1750 key: :report_uri,
1751 label: "Report URI",
1752 type: :string,
1753 description: "Adds the specified URL to report-uri and report-to group in CSP header",
1754 suggestions: ["https://example.com/report-uri"]
1755 }
1756 ]
1757 },
1758 %{
1759 group: :web_push_encryption,
1760 key: :vapid_details,
1761 label: "Vapid Details",
1762 type: :group,
1763 description:
1764 "Web Push Notifications configuration. You can use the mix task mix web_push.gen.keypair to generate it.",
1765 children: [
1766 %{
1767 key: :subject,
1768 type: :string,
1769 description:
1770 "A mailto link for the administrative contact." <>
1771 " It's best if this email is not a personal email address, but rather a group email to the instance moderation team.",
1772 suggestions: ["mailto:moderators@pleroma.com"]
1773 },
1774 %{
1775 key: :public_key,
1776 type: :string,
1777 description: "VAPID public key",
1778 suggestions: ["Public key"]
1779 },
1780 %{
1781 key: :private_key,
1782 type: :string,
1783 description: "VAPID private key",
1784 suggestions: ["Private key"]
1785 }
1786 ]
1787 },
1788 %{
1789 group: :pleroma,
1790 key: Pleroma.Captcha,
1791 type: :group,
1792 description: "Captcha-related settings",
1793 children: [
1794 %{
1795 key: :enabled,
1796 type: :boolean,
1797 description: "Whether the captcha should be shown on registration"
1798 },
1799 %{
1800 key: :method,
1801 type: :module,
1802 description: "The method/service to use for captcha",
1803 suggestions: [Pleroma.Captcha.Kocaptcha, Pleroma.Captcha.Native]
1804 },
1805 %{
1806 key: :seconds_valid,
1807 type: :integer,
1808 description: "The time in seconds for which the captcha is valid",
1809 suggestions: [60]
1810 }
1811 ]
1812 },
1813 %{
1814 group: :pleroma,
1815 key: Pleroma.Captcha.Kocaptcha,
1816 type: :group,
1817 description:
1818 "Kocaptcha is a very simple captcha service with a single API endpoint, the source code is" <>
1819 " here: https://github.com/koto-bank/kocaptcha. The default endpoint (https://captcha.kotobank.ch) is hosted by the developer.",
1820 children: [
1821 %{
1822 key: :endpoint,
1823 type: :string,
1824 description: "The kocaptcha endpoint to use",
1825 suggestions: ["https://captcha.kotobank.ch"]
1826 }
1827 ]
1828 },
1829 %{
1830 group: :pleroma,
1831 label: "Pleroma Admin Token",
1832 type: :group,
1833 description:
1834 "Allows setting a token that can be used to authenticate requests with admin privileges without a normal user account token. Append the `admin_token` parameter to requests to utilize it. (Please reconsider using HTTP Basic Auth or OAuth-based authentication if possible)",
1835 children: [
1836 %{
1837 key: :admin_token,
1838 type: :string,
1839 description: "Admin token",
1840 suggestions: [
1841 "Please use a high entropy string or UUID"
1842 ]
1843 }
1844 ]
1845 },
1846 %{
1847 group: :pleroma,
1848 key: Oban,
1849 type: :group,
1850 description:
1851 "[Oban](https://github.com/sorentwo/oban) asynchronous job processor configuration.",
1852 children: [
1853 %{
1854 key: :log,
1855 type: {:dropdown, :atom},
1856 description: "Logs verbose mode",
1857 suggestions: [false, :error, :warn, :info, :debug]
1858 },
1859 %{
1860 key: :queues,
1861 type: {:keyword, :integer},
1862 description:
1863 "Background jobs queues (keys: queues, values: max numbers of concurrent jobs)",
1864 suggestions: [
1865 activity_expiration: 10,
1866 attachments_cleanup: 5,
1867 background: 5,
1868 federator_incoming: 50,
1869 federator_outgoing: 50,
1870 mailer: 10,
1871 scheduled_activities: 10,
1872 transmogrifier: 20,
1873 web_push: 50
1874 ],
1875 children: [
1876 %{
1877 key: :activity_expiration,
1878 type: :integer,
1879 description: "Activity expiration queue",
1880 suggestions: [10]
1881 },
1882 %{
1883 key: :backup,
1884 type: :integer,
1885 description: "Backup queue",
1886 suggestions: [1]
1887 },
1888 %{
1889 key: :attachments_cleanup,
1890 type: :integer,
1891 description: "Attachment deletion queue",
1892 suggestions: [5]
1893 },
1894 %{
1895 key: :background,
1896 type: :integer,
1897 description: "Background queue",
1898 suggestions: [5]
1899 },
1900 %{
1901 key: :federator_incoming,
1902 type: :integer,
1903 description: "Incoming federation queue",
1904 suggestions: [50]
1905 },
1906 %{
1907 key: :federator_outgoing,
1908 type: :integer,
1909 description: "Outgoing federation queue",
1910 suggestions: [50]
1911 },
1912 %{
1913 key: :mailer,
1914 type: :integer,
1915 description: "Email sender queue, see Pleroma.Emails.Mailer",
1916 suggestions: [10]
1917 },
1918 %{
1919 key: :scheduled_activities,
1920 type: :integer,
1921 description: "Scheduled activities queue, see Pleroma.ScheduledActivities",
1922 suggestions: [10]
1923 },
1924 %{
1925 key: :transmogrifier,
1926 type: :integer,
1927 description: "Transmogrifier queue",
1928 suggestions: [20]
1929 },
1930 %{
1931 key: :web_push,
1932 type: :integer,
1933 description: "Web push notifications queue",
1934 suggestions: [50]
1935 }
1936 ]
1937 },
1938 %{
1939 key: :crontab,
1940 type: {:list, :tuple},
1941 description: "Settings for cron background jobs",
1942 suggestions: [
1943 {"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker},
1944 {"0 0 * * *", Pleroma.Workers.Cron.NewUsersDigestWorker}
1945 ]
1946 }
1947 ]
1948 },
1949 %{
1950 group: :pleroma,
1951 key: :workers,
1952 type: :group,
1953 description: "Includes custom worker options not interpretable directly by `Oban`",
1954 children: [
1955 %{
1956 key: :retries,
1957 type: {:keyword, :integer},
1958 description: "Max retry attempts for failed jobs, per `Oban` queue",
1959 suggestions: [
1960 federator_incoming: 5,
1961 federator_outgoing: 5
1962 ]
1963 }
1964 ]
1965 },
1966 %{
1967 group: :pleroma,
1968 key: Pleroma.Web.Metadata,
1969 type: :group,
1970 description: "Metadata-related settings",
1971 children: [
1972 %{
1973 key: :providers,
1974 type: {:list, :module},
1975 description: "List of metadata providers to enable",
1976 suggestions: [
1977 Pleroma.Web.Metadata.Providers.OpenGraph,
1978 Pleroma.Web.Metadata.Providers.TwitterCard,
1979 Pleroma.Web.Metadata.Providers.RelMe,
1980 Pleroma.Web.Metadata.Providers.Feed
1981 ]
1982 },
1983 %{
1984 key: :unfurl_nsfw,
1985 label: "Unfurl NSFW",
1986 type: :boolean,
1987 description: "When enabled NSFW attachments will be shown in previews"
1988 }
1989 ]
1990 },
1991 %{
1992 group: :pleroma,
1993 key: :rich_media,
1994 type: :group,
1995 description:
1996 "If enabled the instance will parse metadata from attached links to generate link previews",
1997 children: [
1998 %{
1999 key: :enabled,
2000 type: :boolean,
2001 description: "Enables RichMedia parsing of URLs"
2002 },
2003 %{
2004 key: :ignore_hosts,
2005 type: {:list, :string},
2006 description: "List of hosts which will be ignored by the metadata parser",
2007 suggestions: ["accounts.google.com", "xss.website"]
2008 },
2009 %{
2010 key: :ignore_tld,
2011 label: "Ignore TLD",
2012 type: {:list, :string},
2013 description: "List TLDs (top-level domains) which will ignore for parse metadata",
2014 suggestions: ["local", "localdomain", "lan"]
2015 },
2016 %{
2017 key: :parsers,
2018 type: {:list, :module},
2019 description:
2020 "List of Rich Media parsers. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parsers.` part), but on adding custom module you need to use full name.",
2021 suggestions: [
2022 Pleroma.Web.RichMedia.Parsers.OEmbed,
2023 Pleroma.Web.RichMedia.Parsers.TwitterCard
2024 ]
2025 },
2026 %{
2027 key: :ttl_setters,
2028 label: "TTL setters",
2029 type: {:list, :module},
2030 description:
2031 "List of rich media TTL setters. Module names are shortened (removed leading `Pleroma.Web.RichMedia.Parser.` part), but on adding custom module you need to use full name.",
2032 suggestions: [
2033 Pleroma.Web.RichMedia.Parser.TTL.AwsSignedUrl
2034 ]
2035 },
2036 %{
2037 key: :failure_backoff,
2038 type: :integer,
2039 description:
2040 "Amount of milliseconds after request failure, during which the request will not be retried.",
2041 suggestions: [60_000]
2042 }
2043 ]
2044 },
2045 %{
2046 group: :pleroma,
2047 key: Pleroma.Formatter,
2048 label: "Linkify",
2049 type: :group,
2050 description:
2051 "Configuration for Pleroma's link formatter which parses mentions, hashtags, and URLs.",
2052 children: [
2053 %{
2054 key: :class,
2055 type: [:string, :boolean],
2056 description: "Specify the class to be added to the generated link. Disable to clear.",
2057 suggestions: ["auto-linker", false]
2058 },
2059 %{
2060 key: :rel,
2061 type: [:string, :boolean],
2062 description: "Override the rel attribute. Disable to clear.",
2063 suggestions: ["ugc", "noopener noreferrer", false]
2064 },
2065 %{
2066 key: :new_window,
2067 type: :boolean,
2068 description: "Link URLs will open in a new window/tab."
2069 },
2070 %{
2071 key: :truncate,
2072 type: [:integer, :boolean],
2073 description:
2074 "Set to a number to truncate URLs longer than the number. Truncated URLs will end in `...`",
2075 suggestions: [15, false]
2076 },
2077 %{
2078 key: :strip_prefix,
2079 type: :boolean,
2080 description: "Strip the scheme prefix."
2081 },
2082 %{
2083 key: :extra,
2084 type: :boolean,
2085 description: "Link URLs with rarely used schemes (magnet, ipfs, irc, etc.)"
2086 },
2087 %{
2088 key: :validate_tld,
2089 type: [:atom, :boolean],
2090 description:
2091 "Set to false to disable TLD validation for URLs/emails. Can be set to :no_scheme to validate TLDs only for URLs without a scheme (e.g `example.com` will be validated, but `http://example.loki` won't)",
2092 suggestions: [:no_scheme, true]
2093 }
2094 ]
2095 },
2096 %{
2097 group: :pleroma,
2098 key: Pleroma.ScheduledActivity,
2099 type: :group,
2100 description: "Scheduled activities settings",
2101 children: [
2102 %{
2103 key: :daily_user_limit,
2104 type: :integer,
2105 description:
2106 "The number of scheduled activities a user is allowed to create in a single day. Default: 25.",
2107 suggestions: [25]
2108 },
2109 %{
2110 key: :total_user_limit,
2111 type: :integer,
2112 description:
2113 "The number of scheduled activities a user is allowed to create in total. Default: 300.",
2114 suggestions: [300]
2115 },
2116 %{
2117 key: :enabled,
2118 type: :boolean,
2119 description: "Whether scheduled activities are sent to the job queue to be executed"
2120 }
2121 ]
2122 },
2123 %{
2124 group: :pleroma,
2125 key: Pleroma.Workers.PurgeExpiredActivity,
2126 type: :group,
2127 description: "Expired activities settings",
2128 children: [
2129 %{
2130 key: :enabled,
2131 type: :boolean,
2132 description: "Enables expired activities addition & deletion"
2133 },
2134 %{
2135 key: :min_lifetime,
2136 type: :integer,
2137 description: "Minimum lifetime for ephemeral activity (in seconds)",
2138 suggestions: [600]
2139 }
2140 ]
2141 },
2142 %{
2143 group: :pleroma,
2144 label: "Pleroma Authenticator",
2145 type: :group,
2146 description: "Authenticator",
2147 children: [
2148 %{
2149 key: Pleroma.Web.Auth.Authenticator,
2150 type: :module,
2151 suggestions: [Pleroma.Web.Auth.PleromaAuthenticator, Pleroma.Web.Auth.LDAPAuthenticator]
2152 }
2153 ]
2154 },
2155 %{
2156 group: :pleroma,
2157 key: :ldap,
2158 label: "LDAP",
2159 type: :group,
2160 description:
2161 "Use LDAP for user authentication. When a user logs in to the Pleroma instance, the name and password" <>
2162 " will be verified by trying to authenticate (bind) to a LDAP server." <>
2163 " If a user exists in the LDAP directory but there is no account with the same name yet on the" <>
2164 " Pleroma instance then a new Pleroma account will be created with the same name as the LDAP user name.",
2165 children: [
2166 %{
2167 key: :enabled,
2168 type: :boolean,
2169 description: "Enables LDAP authentication"
2170 },
2171 %{
2172 key: :host,
2173 type: :string,
2174 description: "LDAP server hostname",
2175 suggestions: ["localhosts"]
2176 },
2177 %{
2178 key: :port,
2179 type: :integer,
2180 description: "LDAP port, e.g. 389 or 636",
2181 suggestions: [389, 636]
2182 },
2183 %{
2184 key: :ssl,
2185 label: "SSL",
2186 type: :boolean,
2187 description: "Enable to use SSL, usually implies the port 636"
2188 },
2189 %{
2190 key: :sslopts,
2191 label: "SSL options",
2192 type: :keyword,
2193 description: "Additional SSL options",
2194 suggestions: [cacertfile: "path/to/file/with/PEM/cacerts", verify: :verify_peer],
2195 children: [
2196 %{
2197 key: :cacertfile,
2198 type: :string,
2199 description: "Path to file with PEM encoded cacerts",
2200 suggestions: ["path/to/file/with/PEM/cacerts"]
2201 },
2202 %{
2203 key: :verify,
2204 type: :atom,
2205 description: "Type of cert verification",
2206 suggestions: [:verify_peer]
2207 }
2208 ]
2209 },
2210 %{
2211 key: :tls,
2212 label: "TLS",
2213 type: :boolean,
2214 description: "Enable to use STARTTLS, usually implies the port 389"
2215 },
2216 %{
2217 key: :tlsopts,
2218 label: "TLS options",
2219 type: :keyword,
2220 description: "Additional TLS options",
2221 suggestions: [cacertfile: "path/to/file/with/PEM/cacerts", verify: :verify_peer],
2222 children: [
2223 %{
2224 key: :cacertfile,
2225 type: :string,
2226 description: "Path to file with PEM encoded cacerts",
2227 suggestions: ["path/to/file/with/PEM/cacerts"]
2228 },
2229 %{
2230 key: :verify,
2231 type: :atom,
2232 description: "Type of cert verification",
2233 suggestions: [:verify_peer]
2234 }
2235 ]
2236 },
2237 %{
2238 key: :base,
2239 type: :string,
2240 description: "LDAP base, e.g. \"dc=example,dc=com\"",
2241 suggestions: ["dc=example,dc=com"]
2242 },
2243 %{
2244 key: :uid,
2245 label: "UID",
2246 type: :string,
2247 description:
2248 "LDAP attribute name to authenticate the user, e.g. when \"cn\", the filter will be \"cn=username,base\"",
2249 suggestions: ["cn"]
2250 }
2251 ]
2252 },
2253 %{
2254 group: :pleroma,
2255 key: :auth,
2256 type: :group,
2257 description: "Authentication / authorization settings",
2258 children: [
2259 %{
2260 key: :enforce_oauth_admin_scope_usage,
2261 label: "Enforce OAuth admin scope usage",
2262 type: :boolean,
2263 description:
2264 "OAuth admin scope requirement toggle. " <>
2265 "If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token " <>
2266 "(client app must support admin scopes). If disabled and token doesn't have admin scope(s), " <>
2267 "`is_admin` user flag grants access to admin-specific actions."
2268 },
2269 %{
2270 key: :auth_template,
2271 type: :string,
2272 description:
2273 "Authentication form template. By default it's `show.html` which corresponds to `lib/pleroma/web/templates/o_auth/o_auth/show.html.ee`.",
2274 suggestions: ["show.html"]
2275 },
2276 %{
2277 key: :oauth_consumer_template,
2278 label: "OAuth consumer template",
2279 type: :string,
2280 description:
2281 "OAuth consumer mode authentication form template. By default it's `consumer.html` which corresponds to" <>
2282 " `lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex`.",
2283 suggestions: ["consumer.html"]
2284 },
2285 %{
2286 key: :oauth_consumer_strategies,
2287 label: "OAuth consumer strategies",
2288 type: {:list, :string},
2289 description:
2290 "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable." <>
2291 " Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\"" <>
2292 " (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_<strategy>).",
2293 suggestions: ["twitter", "keycloak:ueberauth_keycloak_strategy"]
2294 }
2295 ]
2296 },
2297 %{
2298 group: :pleroma,
2299 key: :email_notifications,
2300 type: :group,
2301 description: "Email notifications settings",
2302 children: [
2303 %{
2304 key: :digest,
2305 type: :map,
2306 description:
2307 "emails of \"what you've missed\" for users who have been inactive for a while",
2308 suggestions: [
2309 %{
2310 active: false,
2311 schedule: "0 0 * * 0",
2312 interval: 7,
2313 inactivity_threshold: 7
2314 }
2315 ],
2316 children: [
2317 %{
2318 key: :active,
2319 label: "Enabled",
2320 type: :boolean,
2321 description: "Globally enable or disable digest emails"
2322 },
2323 %{
2324 key: :schedule,
2325 type: :string,
2326 description:
2327 "When to send digest email, in crontab format. \"0 0 0\" is the default, meaning \"once a week at midnight on Sunday morning\".",
2328 suggestions: ["0 0 * * 0"]
2329 },
2330 %{
2331 key: :interval,
2332 type: :integer,
2333 description: "Minimum interval between digest emails to one user",
2334 suggestions: [7]
2335 },
2336 %{
2337 key: :inactivity_threshold,
2338 type: :integer,
2339 description: "Minimum user inactivity threshold",
2340 suggestions: [7]
2341 }
2342 ]
2343 }
2344 ]
2345 },
2346 %{
2347 group: :pleroma,
2348 key: Pleroma.Emails.UserEmail,
2349 type: :group,
2350 description: "Email template settings",
2351 children: [
2352 %{
2353 key: :logo,
2354 type: {:string, :image},
2355 description: "A path to a custom logo. Set it to `nil` to use the default Pleroma logo.",
2356 suggestions: ["some/path/logo.png"]
2357 },
2358 %{
2359 key: :styling,
2360 type: :map,
2361 description: "A map with color settings for email templates.",
2362 suggestions: [
2363 %{
2364 link_color: "#d8a070",
2365 background_color: "#2C3645",
2366 content_background_color: "#1B2635",
2367 header_color: "#d8a070",
2368 text_color: "#b9b9ba",
2369 text_muted_color: "#b9b9ba"
2370 }
2371 ],
2372 children: [
2373 %{
2374 key: :link_color,
2375 type: :string,
2376 suggestions: ["#d8a070"]
2377 },
2378 %{
2379 key: :background_color,
2380 type: :string,
2381 suggestions: ["#2C3645"]
2382 },
2383 %{
2384 key: :content_background_color,
2385 type: :string,
2386 suggestions: ["#1B2635"]
2387 },
2388 %{
2389 key: :header_color,
2390 type: :string,
2391 suggestions: ["#d8a070"]
2392 },
2393 %{
2394 key: :text_color,
2395 type: :string,
2396 suggestions: ["#b9b9ba"]
2397 },
2398 %{
2399 key: :text_muted_color,
2400 type: :string,
2401 suggestions: ["#b9b9ba"]
2402 }
2403 ]
2404 }
2405 ]
2406 },
2407 %{
2408 group: :pleroma,
2409 key: Pleroma.Emails.NewUsersDigestEmail,
2410 type: :group,
2411 description: "New users admin email digest",
2412 children: [
2413 %{
2414 key: :enabled,
2415 type: :boolean,
2416 description: "Enables new users admin digest email when `true`"
2417 }
2418 ]
2419 },
2420 %{
2421 group: :pleroma,
2422 key: :oauth2,
2423 label: "OAuth2",
2424 type: :group,
2425 description: "Configure OAuth 2 provider capabilities",
2426 children: [
2427 %{
2428 key: :token_expires_in,
2429 type: :integer,
2430 description: "The lifetime in seconds of the access token",
2431 suggestions: [2_592_000]
2432 },
2433 %{
2434 key: :issue_new_refresh_token,
2435 type: :boolean,
2436 description:
2437 "Keeps old refresh token or generate new refresh token when to obtain an access token"
2438 },
2439 %{
2440 key: :clean_expired_tokens,
2441 type: :boolean,
2442 description: "Enable a background job to clean expired OAuth tokens. Default: disabled."
2443 }
2444 ]
2445 },
2446 %{
2447 group: :pleroma,
2448 key: :emoji,
2449 type: :group,
2450 children: [
2451 %{
2452 key: :shortcode_globs,
2453 type: {:list, :string},
2454 description: "Location of custom emoji files. * can be used as a wildcard.",
2455 suggestions: ["/emoji/custom/**/*.png"]
2456 },
2457 %{
2458 key: :pack_extensions,
2459 type: {:list, :string},
2460 description:
2461 "A list of file extensions for emojis, when no emoji.txt for a pack is present",
2462 suggestions: [".png", ".gif"]
2463 },
2464 %{
2465 key: :groups,
2466 type: {:keyword, {:list, :string}},
2467 description:
2468 "Emojis are ordered in groups (tags). This is an array of key-value pairs where the key is the group name" <>
2469 " and the value is the location or array of locations. * can be used as a wildcard.",
2470 suggestions: [
2471 Custom: ["/emoji/*.png", "/emoji/**/*.png"]
2472 ]
2473 },
2474 %{
2475 key: :default_manifest,
2476 type: :string,
2477 description:
2478 "Location of the JSON-manifest. This manifest contains information about the emoji-packs you can download." <>
2479 " Currently only one manifest can be added (no arrays).",
2480 suggestions: ["https://git.pleroma.social/pleroma/emoji-index/raw/master/index.json"]
2481 },
2482 %{
2483 key: :shared_pack_cache_seconds_per_file,
2484 label: "Shared pack cache s/file",
2485 type: :integer,
2486 descpiption:
2487 "When an emoji pack is shared, the archive is created and cached in memory" <>
2488 " for this amount of seconds multiplied by the number of files.",
2489 suggestions: [60]
2490 }
2491 ]
2492 },
2493 %{
2494 group: :pleroma,
2495 key: :rate_limit,
2496 type: :group,
2497 description:
2498 "Rate limit settings. This is an advanced feature enabled only for :authentication by default.",
2499 children: [
2500 %{
2501 key: :search,
2502 type: [:tuple, {:list, :tuple}],
2503 description: "For the search requests (account & status search etc.)",
2504 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2505 },
2506 %{
2507 key: :timeline,
2508 type: [:tuple, {:list, :tuple}],
2509 description: "For requests to timelines (each timeline has it's own limiter)",
2510 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2511 },
2512 %{
2513 key: :app_account_creation,
2514 type: [:tuple, {:list, :tuple}],
2515 description: "For registering user accounts from the same IP address",
2516 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2517 },
2518 %{
2519 key: :relations_actions,
2520 type: [:tuple, {:list, :tuple}],
2521 description: "For actions on relationships with all users (follow, unfollow)",
2522 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2523 },
2524 %{
2525 key: :relation_id_action,
2526 label: "Relation ID action",
2527 type: [:tuple, {:list, :tuple}],
2528 description: "For actions on relation with a specific user (follow, unfollow)",
2529 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2530 },
2531 %{
2532 key: :statuses_actions,
2533 type: [:tuple, {:list, :tuple}],
2534 description:
2535 "For create / delete / fav / unfav / reblog / unreblog actions on any statuses",
2536 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2537 },
2538 %{
2539 key: :status_id_action,
2540 label: "Status ID action",
2541 type: [:tuple, {:list, :tuple}],
2542 description:
2543 "For fav / unfav or reblog / unreblog actions on the same status by the same user",
2544 suggestions: [{1000, 10}, [{10_000, 10}, {10_000, 50}]]
2545 },
2546 %{
2547 key: :authentication,
2548 type: [:tuple, {:list, :tuple}],
2549 description: "For authentication create / password check / user existence check requests",
2550 suggestions: [{60_000, 15}]
2551 }
2552 ]
2553 },
2554 %{
2555 group: :esshd,
2556 label: "ESSHD",
2557 type: :group,
2558 description:
2559 "Before enabling this you must add :esshd to mix.exs as one of the extra_applications " <>
2560 "and generate host keys in your priv dir with ssh-keygen -m PEM -N \"\" -b 2048 -t rsa -f ssh_host_rsa_key",
2561 children: [
2562 %{
2563 key: :enabled,
2564 type: :boolean,
2565 description: "Enables SSH"
2566 },
2567 %{
2568 key: :priv_dir,
2569 type: :string,
2570 description: "Dir with SSH keys",
2571 suggestions: ["/some/path/ssh_keys"]
2572 },
2573 %{
2574 key: :handler,
2575 type: :string,
2576 description: "Handler module",
2577 suggestions: ["Pleroma.BBS.Handler"]
2578 },
2579 %{
2580 key: :port,
2581 type: :integer,
2582 description: "Port to connect",
2583 suggestions: [10_022]
2584 },
2585 %{
2586 key: :password_authenticator,
2587 type: :string,
2588 description: "Authenticator module",
2589 suggestions: ["Pleroma.BBS.Authenticator"]
2590 }
2591 ]
2592 },
2593 %{
2594 group: :mime,
2595 label: "Mime Types",
2596 type: :group,
2597 description: "Mime Types settings",
2598 children: [
2599 %{
2600 key: :types,
2601 type: :map,
2602 suggestions: [
2603 %{
2604 "application/xml" => ["xml"],
2605 "application/xrd+xml" => ["xrd+xml"],
2606 "application/jrd+json" => ["jrd+json"],
2607 "application/activity+json" => ["activity+json"],
2608 "application/ld+json" => ["activity+json"]
2609 }
2610 ],
2611 children: [
2612 %{
2613 key: "application/xml",
2614 type: {:list, :string},
2615 suggestions: ["xml"]
2616 },
2617 %{
2618 key: "application/xrd+xml",
2619 type: {:list, :string},
2620 suggestions: ["xrd+xml"]
2621 },
2622 %{
2623 key: "application/jrd+json",
2624 type: {:list, :string},
2625 suggestions: ["jrd+json"]
2626 },
2627 %{
2628 key: "application/activity+json",
2629 type: {:list, :string},
2630 suggestions: ["activity+json"]
2631 },
2632 %{
2633 key: "application/ld+json",
2634 type: {:list, :string},
2635 suggestions: ["activity+json"]
2636 }
2637 ]
2638 }
2639 ]
2640 },
2641 %{
2642 group: :pleroma,
2643 key: :chat,
2644 type: :group,
2645 description: "Pleroma chat settings",
2646 children: [
2647 %{
2648 key: :enabled,
2649 type: :boolean
2650 }
2651 ]
2652 },
2653 %{
2654 group: :pleroma,
2655 key: :http,
2656 label: "HTTP",
2657 type: :group,
2658 description: "HTTP settings",
2659 children: [
2660 %{
2661 key: :proxy_url,
2662 label: "Proxy URL",
2663 type: [:string, :tuple],
2664 description: "Proxy URL",
2665 suggestions: ["localhost:9020", {:socks5, :localhost, 3090}]
2666 },
2667 %{
2668 key: :send_user_agent,
2669 type: :boolean
2670 },
2671 %{
2672 key: :user_agent,
2673 type: [:string, :atom],
2674 description:
2675 "What user agent to use. Must be a string or an atom `:default`. Default value is `:default`.",
2676 suggestions: ["Pleroma", :default]
2677 },
2678 %{
2679 key: :adapter,
2680 type: :keyword,
2681 description: "Adapter specific options",
2682 suggestions: [],
2683 children: [
2684 %{
2685 key: :ssl_options,
2686 type: :keyword,
2687 label: "SSL Options",
2688 description: "SSL options for HTTP adapter",
2689 children: [
2690 %{
2691 key: :versions,
2692 type: {:list, :atom},
2693 description: "List of TLS version to use",
2694 suggestions: [:tlsv1, ":tlsv1.1", ":tlsv1.2"]
2695 }
2696 ]
2697 }
2698 ]
2699 }
2700 ]
2701 },
2702 %{
2703 group: :pleroma,
2704 key: :markup,
2705 label: "Markup Settings",
2706 type: :group,
2707 children: [
2708 %{
2709 key: :allow_inline_images,
2710 type: :boolean
2711 },
2712 %{
2713 key: :allow_headings,
2714 type: :boolean
2715 },
2716 %{
2717 key: :allow_tables,
2718 type: :boolean
2719 },
2720 %{
2721 key: :allow_fonts,
2722 type: :boolean
2723 },
2724 %{
2725 key: :scrub_policy,
2726 type: {:list, :module},
2727 description:
2728 "Module names are shortened (removed leading `Pleroma.HTML.` part), but on adding custom module you need to use full name.",
2729 suggestions: [Pleroma.HTML.Transform.MediaProxy, Pleroma.HTML.Scrubber.Default]
2730 }
2731 ]
2732 },
2733 %{
2734 group: :pleroma,
2735 key: :user,
2736 type: :group,
2737 children: [
2738 %{
2739 key: :deny_follow_blocked,
2740 type: :boolean
2741 }
2742 ]
2743 },
2744 %{
2745 group: :pleroma,
2746 key: Pleroma.User,
2747 type: :group,
2748 children: [
2749 %{
2750 key: :restricted_nicknames,
2751 type: {:list, :string},
2752 description: "List of nicknames users may not register with.",
2753 suggestions: [
2754 ".well-known",
2755 "~",
2756 "about",
2757 "activities",
2758 "api",
2759 "auth",
2760 "check_password",
2761 "dev",
2762 "friend-requests",
2763 "inbox",
2764 "internal",
2765 "main",
2766 "media",
2767 "nodeinfo",
2768 "notice",
2769 "oauth",
2770 "objects",
2771 "ostatus_subscribe",
2772 "pleroma",
2773 "proxy",
2774 "push",
2775 "registration",
2776 "relay",
2777 "settings",
2778 "status",
2779 "tag",
2780 "user-search",
2781 "user_exists",
2782 "users",
2783 "web"
2784 ]
2785 },
2786 %{
2787 key: :email_blacklist,
2788 type: {:list, :string},
2789 description: "List of email domains users may not register with.",
2790 suggestions: ["mailinator.com", "maildrop.cc"]
2791 }
2792 ]
2793 },
2794 %{
2795 group: :cors_plug,
2796 label: "CORS plug config",
2797 type: :group,
2798 children: [
2799 %{
2800 key: :max_age,
2801 type: :integer,
2802 suggestions: [86_400]
2803 },
2804 %{
2805 key: :methods,
2806 type: {:list, :string},
2807 suggestions: ["POST", "PUT", "DELETE", "GET", "PATCH", "OPTIONS"]
2808 },
2809 %{
2810 key: :expose,
2811 type: {:list, :string},
2812 suggestions: [
2813 "Link",
2814 "X-RateLimit-Reset",
2815 "X-RateLimit-Limit",
2816 "X-RateLimit-Remaining",
2817 "X-Request-Id",
2818 "Idempotency-Key"
2819 ]
2820 },
2821 %{
2822 key: :credentials,
2823 type: :boolean
2824 },
2825 %{
2826 key: :headers,
2827 type: {:list, :string},
2828 suggestions: ["Authorization", "Content-Type", "Idempotency-Key"]
2829 }
2830 ]
2831 },
2832 %{
2833 group: :pleroma,
2834 key: Pleroma.Web.Plugs.RemoteIp,
2835 type: :group,
2836 description: """
2837 `Pleroma.Web.Plugs.RemoteIp` is a shim to call [`RemoteIp`](https://git.pleroma.social/pleroma/remote_ip) but with runtime configuration.
2838 **If your instance is not behind at least one reverse proxy, you should not enable this plug.**
2839 """,
2840 children: [
2841 %{
2842 key: :enabled,
2843 type: :boolean,
2844 description: "Enable/disable the plug. Default: disabled."
2845 },
2846 %{
2847 key: :headers,
2848 type: {:list, :string},
2849 description: """
2850 A list of strings naming the HTTP headers to use when deriving the true client IP. Default: `["x-forwarded-for"]`.
2851 """
2852 },
2853 %{
2854 key: :proxies,
2855 type: {:list, :string},
2856 description:
2857 "A list of upstream proxy IP subnets in CIDR notation from which we will parse the content of `headers`. Defaults to `[]`. IPv4 entries without a bitmask will be assumed to be /32 and IPv6 /128."
2858 },
2859 %{
2860 key: :reserved,
2861 type: {:list, :string},
2862 description: """
2863 A list of reserved IP subnets in CIDR notation which should be ignored if found in `headers`. Defaults to `["127.0.0.0/8", "::1/128", "fc00::/7", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]`
2864 """
2865 }
2866 ]
2867 },
2868 %{
2869 group: :pleroma,
2870 key: :web_cache_ttl,
2871 label: "Web cache TTL",
2872 type: :group,
2873 description:
2874 "The expiration time for the web responses cache. Values should be in milliseconds or `nil` to disable expiration.",
2875 children: [
2876 %{
2877 key: :activity_pub,
2878 type: :integer,
2879 description:
2880 "Activity pub routes (except question activities). Default: `nil` (no expiration).",
2881 suggestions: [30_000, nil]
2882 },
2883 %{
2884 key: :activity_pub_question,
2885 type: :integer,
2886 description: "Activity pub routes (question activities). Default: `30_000` (30 seconds).",
2887 suggestions: [30_000]
2888 }
2889 ]
2890 },
2891 %{
2892 group: :pleroma,
2893 key: :static_fe,
2894 label: "Static FE",
2895 type: :group,
2896 description:
2897 "Render profiles and posts using server-generated HTML that is viewable without using JavaScript",
2898 children: [
2899 %{
2900 key: :enabled,
2901 type: :boolean,
2902 description: "Enables the rendering of static HTML. Default: disabled."
2903 }
2904 ]
2905 },
2906 %{
2907 group: :pleroma,
2908 key: :feed,
2909 type: :group,
2910 description: "Configure feed rendering",
2911 children: [
2912 %{
2913 key: :post_title,
2914 type: :map,
2915 description: "Configure title rendering",
2916 children: [
2917 %{
2918 key: :max_length,
2919 type: :integer,
2920 description: "Maximum number of characters before truncating title",
2921 suggestions: [100]
2922 },
2923 %{
2924 key: :omission,
2925 type: :string,
2926 description: "Replacement which will be used after truncating string",
2927 suggestions: ["..."]
2928 }
2929 ]
2930 }
2931 ]
2932 },
2933 %{
2934 group: :pleroma,
2935 key: :modules,
2936 type: :group,
2937 description: "Custom Runtime Modules",
2938 children: [
2939 %{
2940 key: :runtime_dir,
2941 type: :string,
2942 description: "A path to custom Elixir modules (such as MRF policies)."
2943 }
2944 ]
2945 },
2946 %{
2947 group: :pleroma,
2948 key: :streamer,
2949 type: :group,
2950 description: "Settings for notifications streamer",
2951 children: [
2952 %{
2953 key: :workers,
2954 type: :integer,
2955 description: "Number of workers to send notifications",
2956 suggestions: [3]
2957 },
2958 %{
2959 key: :overflow_workers,
2960 type: :integer,
2961 description: "Maximum number of workers created if pool is empty",
2962 suggestions: [2]
2963 }
2964 ]
2965 },
2966 %{
2967 group: :pleroma,
2968 key: :connections_pool,
2969 type: :group,
2970 description: "Advanced settings for `Gun` connections pool",
2971 children: [
2972 %{
2973 key: :connection_acquisition_wait,
2974 type: :integer,
2975 description:
2976 "Timeout to acquire a connection from pool. The total max time is this value multiplied by the number of retries. Default: 250ms.",
2977 suggestions: [250]
2978 },
2979 %{
2980 key: :connection_acquisition_retries,
2981 type: :integer,
2982 description:
2983 "Number of attempts to acquire the connection from the pool if it is overloaded. Default: 5",
2984 suggestions: [5]
2985 },
2986 %{
2987 key: :max_connections,
2988 type: :integer,
2989 description: "Maximum number of connections in the pool. Default: 250 connections.",
2990 suggestions: [250]
2991 },
2992 %{
2993 key: :connect_timeout,
2994 type: :integer,
2995 description: "Timeout while `gun` will wait until connection is up. Default: 5000ms.",
2996 suggestions: [5000]
2997 },
2998 %{
2999 key: :reclaim_multiplier,
3000 type: :integer,
3001 description:
3002 "Multiplier for the number of idle connection to be reclaimed if the pool is full. For example if the pool maxes out at 250 connections and this setting is set to 0.3, the pool will reclaim at most 75 idle connections if it's overloaded. Default: 0.1",
3003 suggestions: [0.1]
3004 }
3005 ]
3006 },
3007 %{
3008 group: :pleroma,
3009 key: :pools,
3010 type: :group,
3011 description: "Advanced settings for `Gun` workers pools",
3012 children:
3013 Enum.map([:federation, :media, :upload, :default], fn pool_name ->
3014 %{
3015 key: pool_name,
3016 type: :keyword,
3017 description: "Settings for #{pool_name} pool.",
3018 children: [
3019 %{
3020 key: :size,
3021 type: :integer,
3022 description: "Maximum number of concurrent requests in the pool.",
3023 suggestions: [50]
3024 },
3025 %{
3026 key: :max_waiting,
3027 type: :integer,
3028 description:
3029 "Maximum number of requests waiting for other requests to finish. After this number is reached, the pool will start returning errrors when a new request is made",
3030 suggestions: [10]
3031 },
3032 %{
3033 key: :recv_timeout,
3034 type: :integer,
3035 description: "Timeout for the pool while gun will wait for response",
3036 suggestions: [10_000]
3037 }
3038 ]
3039 }
3040 end)
3041 },
3042 %{
3043 group: :pleroma,
3044 key: :hackney_pools,
3045 type: :group,
3046 description: "Advanced settings for `Hackney` connections pools",
3047 children: [
3048 %{
3049 key: :federation,
3050 type: :keyword,
3051 description: "Settings for federation pool.",
3052 children: [
3053 %{
3054 key: :max_connections,
3055 type: :integer,
3056 description: "Number workers in the pool.",
3057 suggestions: [50]
3058 },
3059 %{
3060 key: :timeout,
3061 type: :integer,
3062 description: "Timeout while `hackney` will wait for response.",
3063 suggestions: [150_000]
3064 }
3065 ]
3066 },
3067 %{
3068 key: :media,
3069 type: :keyword,
3070 description: "Settings for media pool.",
3071 children: [
3072 %{
3073 key: :max_connections,
3074 type: :integer,
3075 description: "Number workers in the pool.",
3076 suggestions: [50]
3077 },
3078 %{
3079 key: :timeout,
3080 type: :integer,
3081 description: "Timeout while `hackney` will wait for response.",
3082 suggestions: [150_000]
3083 }
3084 ]
3085 },
3086 %{
3087 key: :upload,
3088 type: :keyword,
3089 description: "Settings for upload pool.",
3090 children: [
3091 %{
3092 key: :max_connections,
3093 type: :integer,
3094 description: "Number workers in the pool.",
3095 suggestions: [25]
3096 },
3097 %{
3098 key: :timeout,
3099 type: :integer,
3100 description: "Timeout while `hackney` will wait for response.",
3101 suggestions: [300_000]
3102 }
3103 ]
3104 }
3105 ]
3106 },
3107 %{
3108 group: :pleroma,
3109 key: :restrict_unauthenticated,
3110 label: "Restrict Unauthenticated",
3111 type: :group,
3112 description:
3113 "Disallow viewing timelines, user profiles and statuses for unauthenticated users.",
3114 children: [
3115 %{
3116 key: :timelines,
3117 type: :map,
3118 description: "Settings for public and federated timelines.",
3119 children: [
3120 %{
3121 key: :local,
3122 type: :boolean,
3123 description: "Disallow view public timeline."
3124 },
3125 %{
3126 key: :federated,
3127 type: :boolean,
3128 description: "Disallow view federated timeline."
3129 }
3130 ]
3131 },
3132 %{
3133 key: :profiles,
3134 type: :map,
3135 description: "Settings for user profiles.",
3136 children: [
3137 %{
3138 key: :local,
3139 type: :boolean,
3140 description: "Disallow view local user profiles."
3141 },
3142 %{
3143 key: :remote,
3144 type: :boolean,
3145 description: "Disallow view remote user profiles."
3146 }
3147 ]
3148 },
3149 %{
3150 key: :activities,
3151 type: :map,
3152 description: "Settings for statuses.",
3153 children: [
3154 %{
3155 key: :local,
3156 type: :boolean,
3157 description: "Disallow view local statuses."
3158 },
3159 %{
3160 key: :remote,
3161 type: :boolean,
3162 description: "Disallow view remote statuses."
3163 }
3164 ]
3165 }
3166 ]
3167 },
3168 %{
3169 group: :pleroma,
3170 key: Pleroma.Web.ApiSpec.CastAndValidate,
3171 type: :group,
3172 children: [
3173 %{
3174 key: :strict,
3175 type: :boolean,
3176 description:
3177 "Enables strict input validation (useful in development, not recommended in production)"
3178 }
3179 ]
3180 },
3181 %{
3182 group: :pleroma,
3183 key: :instances_favicons,
3184 type: :group,
3185 description: "Control favicons for instances",
3186 children: [
3187 %{
3188 key: :enabled,
3189 type: :boolean,
3190 description: "Allow/disallow displaying and getting instances favicons"
3191 }
3192 ]
3193 },
3194 %{
3195 group: :ex_aws,
3196 key: :s3,
3197 type: :group,
3198 descriptions: "S3 service related settings",
3199 children: [
3200 %{
3201 key: :access_key_id,
3202 type: :string,
3203 description: "S3 access key ID",
3204 suggestions: ["AKIAQ8UKHTGIYN7DMWWJ"]
3205 },
3206 %{
3207 key: :secret_access_key,
3208 type: :string,
3209 description: "Secret access key",
3210 suggestions: ["JFGt+fgH1UQ7vLUQjpW+WvjTdV/UNzVxcwn7DkaeFKtBS5LvoXvIiME4NQBsT6ZZ"]
3211 },
3212 %{
3213 key: :host,
3214 type: :string,
3215 description: "S3 host",
3216 suggestions: ["s3.eu-central-1.amazonaws.com"]
3217 },
3218 %{
3219 key: :region,
3220 type: :string,
3221 description: "S3 region (for AWS)",
3222 suggestions: ["us-east-1"]
3223 }
3224 ]
3225 },
3226 %{
3227 group: :pleroma,
3228 key: :frontends,
3229 type: :group,
3230 description: "Installed frontends management",
3231 children: [
3232 %{
3233 key: :primary,
3234 type: :map,
3235 description: "Primary frontend, the one that is served for all pages by default",
3236 children: installed_frontend_options
3237 },
3238 %{
3239 key: :admin,
3240 type: :map,
3241 description: "Admin frontend",
3242 children: installed_frontend_options
3243 },
3244 %{
3245 key: :available,
3246 type: :map,
3247 description:
3248 "A map containing available frontends and parameters for their installation.",
3249 children: frontend_options
3250 }
3251 ]
3252 },
3253 %{
3254 group: :pleroma,
3255 key: Pleroma.Web.Preload,
3256 type: :group,
3257 description: "Preload-related settings",
3258 children: [
3259 %{
3260 key: :providers,
3261 type: {:list, :module},
3262 description: "List of preload providers to enable",
3263 suggestions: [
3264 Pleroma.Web.Preload.Providers.Instance,
3265 Pleroma.Web.Preload.Providers.User,
3266 Pleroma.Web.Preload.Providers.Timelines,
3267 Pleroma.Web.Preload.Providers.StatusNet
3268 ]
3269 }
3270 ]
3271 },
3272 %{
3273 group: :pleroma,
3274 key: :majic_pool,
3275 type: :group,
3276 description: "Majic/libmagic configuration",
3277 children: [
3278 %{
3279 key: :size,
3280 type: :integer,
3281 description: "Number of majic workers to start.",
3282 suggestions: [2]
3283 }
3284 ]
3285 },
3286 %{
3287 group: :pleroma,
3288 key: Pleroma.User.Backup,
3289 type: :group,
3290 description: "Account Backup",
3291 children: [
3292 %{
3293 key: :purge_after_days,
3294 type: :integer,
3295 description: "Remove backup achives after N days",
3296 suggestions: [30]
3297 },
3298 %{
3299 key: :limit_days,
3300 type: :integer,
3301 description: "Limit user to export not more often than once per N days",
3302 suggestions: [7]
3303 }
3304 ]
3305 },
3306 %{
3307 group: :prometheus,
3308 key: Pleroma.Web.Endpoint.MetricsExporter,
3309 type: :group,
3310 description: "Prometheus app metrics endpoint configuration",
3311 children: [
3312 %{
3313 key: :enabled,
3314 type: :boolean,
3315 description: "[Pleroma extension] Enables app metrics endpoint."
3316 },
3317 %{
3318 key: :ip_whitelist,
3319 type: [{:list, :string}, {:list, :charlist}, {:list, :tuple}],
3320 description:
3321 "[Pleroma extension] If non-empty, restricts access to app metrics endpoint to specified IP addresses."
3322 },
3323 %{
3324 key: :auth,
3325 type: [:boolean, :tuple],
3326 description: "Enables HTTP Basic Auth for app metrics endpoint.",
3327 suggestion: [false, {:basic, "myusername", "mypassword"}]
3328 },
3329 %{
3330 key: :path,
3331 type: :string,
3332 description: "App metrics endpoint URI path.",
3333 suggestions: ["/api/pleroma/app_metrics"]
3334 },
3335 %{
3336 key: :format,
3337 type: :atom,
3338 description: "App metrics endpoint output format.",
3339 suggestions: [:text, :protobuf]
3340 }
3341 ]
3342 },
3343 %{
3344 group: :pleroma,
3345 key: ConcurrentLimiter,
3346 type: :group,
3347 description: "Limits configuration for background tasks.",
3348 children: [
3349 %{
3350 key: Pleroma.Web.RichMedia.Helpers,
3351 type: :keyword,
3352 description: "Concurrent limits configuration for getting RichMedia for activities.",
3353 suggestions: [max_running: 5, max_waiting: 5],
3354 children: [
3355 %{
3356 key: :max_running,
3357 type: :integer,
3358 description: "Max running concurrently jobs.",
3359 suggestion: [5]
3360 },
3361 %{
3362 key: :max_waiting,
3363 type: :integer,
3364 description: "Max waiting jobs.",
3365 suggestion: [5]
3366 }
3367 ]
3368 },
3369 %{
3370 key: Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy,
3371 type: :keyword,
3372 description: "Concurrent limits configuration for MediaProxyWarmingPolicy.",
3373 suggestions: [max_running: 5, max_waiting: 5],
3374 children: [
3375 %{
3376 key: :max_running,
3377 type: :integer,
3378 description: "Max running concurrently jobs.",
3379 suggestion: [5]
3380 },
3381 %{
3382 key: :max_waiting,
3383 type: :integer,
3384 description: "Max waiting jobs.",
3385 suggestion: [5]
3386 }
3387 ]
3388 }
3389 ]
3390 }
3391 ]