From fd64a1e264d828c6248dfe3fe12631af4e93a22c Mon Sep 17 00:00:00 2001 From: tobi Date: Mon, 26 May 2025 13:28:55 +0200 Subject: [feature] Add "Instance Info" settings panel section, with domain blocks + allows (#4193) This pull request adds a new read-only, user-level "instance info" section to the settings panel, which presents api/v2/instance info in a nice readable format, and also gives the user authenticated access to the blocklist and allowlist of the domain. Closes https://codeberg.org/superseriousbusiness/gotosocial/issues/3711 Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4193 Co-authored-by: tobi Co-committed-by: tobi --- web/source/settings/views/user/instance/index.tsx | 287 ++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 web/source/settings/views/user/instance/index.tsx (limited to 'web/source/settings/views/user/instance') diff --git a/web/source/settings/views/user/instance/index.tsx b/web/source/settings/views/user/instance/index.tsx new file mode 100644 index 000000000..0e0643bd7 --- /dev/null +++ b/web/source/settings/views/user/instance/index.tsx @@ -0,0 +1,287 @@ +/* + GoToSocial + Copyright (C) GoToSocial Authors admin@gotosocial.org + SPDX-License-Identifier: AGPL-3.0-or-later + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +import React, { useMemo } from "react"; +import { useInstanceV2Query } from "../../../lib/query/gts-api"; +import Loading from "../../../components/loading"; +import { InstanceV2 } from "../../../lib/types/instance"; +import { useHumanReadableBytes, useHumanReadableDuration, yesOrNo } from "../../../lib/util"; +import { HighlightedCode } from "../../../components/highlightedcode"; +import { useInstanceDomainAllowsQuery, useInstanceDomainBlocksQuery } from "../../../lib/query/user/domainperms"; + +export default function InstanceInfo() { + // Load instance v2 data. + const { + data, + isFetching, + isLoading, + } = useInstanceV2Query(); + + if (isFetching || isLoading) { + return ; + } + + if (data === undefined) { + throw "could not fetch instance v2"; + } + + return ( +
+
+

Instance Info

+

+ On this page you can see information about this instance, and view domain blocks + and domain allows that have been created by the admin(s) of the instance. +

+
+ + + +
+ ); +} + +function Instance({ instance }: { instance: InstanceV2 }) { + const emojiSizeLimit = useHumanReadableBytes(instance.configuration.emojis.emoji_size_limit); + const accountsCustomCSS = yesOrNo(instance.configuration.accounts.allow_custom_css); + const imageSizeLimit = useHumanReadableBytes(instance.configuration.media_attachments.image_size_limit); + const videoSizeLimit = useHumanReadableBytes(instance.configuration.media_attachments.video_size_limit); + const pollMinExpiry = useHumanReadableDuration(instance.configuration.polls.min_expiration); + const pollMaxExpiry = useHumanReadableDuration(instance.configuration.polls.max_expiration); + + return ( + <> +
+
+
Software version:
+
+ + {instance.version} + +
+
+ +
+
Streaming URL:
+
{instance.configuration.urls.streaming}
+
+ +
+
Emoji size limit:
+
{emojiSizeLimit}
+
+ +
+
Accounts custom CSS:
+
{accountsCustomCSS}
+
+ +
+
Accounts max featured tags:
+
{instance.configuration.accounts.max_featured_tags}
+
+ +
+
Accounts max profile fields:
+
{instance.configuration.accounts.max_profile_fields}
+
+ +
+
Posts max characters:
+
{instance.configuration.statuses.max_characters}
+
+ +
+
Posts max attachments:
+
{instance.configuration.statuses.max_media_attachments}
+
+ +
+
Posts supported types:
+
+ { useJoinWithNewlines(instance.configuration.statuses.supported_mime_types) } +
+
+ +
+
Polls max options:
+
{instance.configuration.polls.max_options}
+
+ +
+
Polls max characters per option:
+
{instance.configuration.polls.max_characters_per_option}
+
+ +
+
Polls min expiration:
+
{pollMinExpiry}
+
+ +
+
Polls max expiration:
+
{pollMaxExpiry}
+
+ +
+
Media max description characters:
+
{instance.configuration.media_attachments.description_limit}
+
+ +
+
Media max image size:
+
{imageSizeLimit}
+
+ +
+
Media max video size:
+
{videoSizeLimit}
+
+ +
+
Media supported types:
+
+ { useJoinWithNewlines(instance.configuration.media_attachments.supported_mime_types) } +
+
+
+ + { instance.custom_css && + <> +
+

Custom CSS

+

The following custom CSS has been set by the admin(s) of this instance, and will be loaded on each web page:

+
+ + + } + + ); +} + +function Allowlist() { + // Load allows. + const { + data, + isFetching, + isLoading, + } = useInstanceDomainAllowsQuery(); + + if (isFetching || isLoading) { + return ; + } + + if (data === undefined) { + throw "could not fetch domain allows"; + } + + return ( + <> +
+

Domain Allows

+

+ The following list of domains has been explicitly allowed by the administrator(s) of this instance. +
This extends to subdomains, so an allowlist entry for domain 'example.com' includes domain 'social.example.com' etc as well. +

+
+ { data.length !== 0 + ?
+
+
Domain
+
Public comment
+
+ { data.map(e => { + return ( +
+
{e.domain}
+
{e.comment}
+
+ ); + }) } +
+ : No explicit allows. + } + + ); +} + +function Blocklist() { + // Load blocks. + const { + data, + isFetching, + isLoading, + } = useInstanceDomainBlocksQuery(); + + if (isFetching || isLoading) { + return ; + } + + if (data === undefined) { + throw "could not fetch domain blocks"; + } + + return ( + <> +
+

Domain Blocks

+

+ The following list of domains has been blocked by the administrator(s) of this instance. +
All past, present, and future accounts at blocked domains are forbidden from interacting with this instance or accounts on this instance. +
No data will be sent to the server at the remote domain, and no data will be received from it. +
This extends to subdomains, so a blocklist entry for domain 'example.com' includes domain 'social.example.com' etc as well. +

+
+ { data.length !== 0 + ?
+
+
Domain
+
Public comment
+
+ { data.map(e => { + return ( +
+
{e.domain}
+
{e.comment}
+
+ ); + }) } +
+ : No domain blocks. + } + + ); +} + +function useJoinWithNewlines(a: string[]) { + return useMemo(() => { + const l = a.length; + return a.map((v, i) => { + const e = {v}; + if (i+1 !== l) { + return [e,
]; + } + return [e]; + }).flat(); + }, [a]); +} -- cgit v1.2.3