diff options
Diffstat (limited to 'web/source/settings/views/admin/http-header-permissions/overview.tsx')
-rw-r--r-- | web/source/settings/views/admin/http-header-permissions/overview.tsx | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/web/source/settings/views/admin/http-header-permissions/overview.tsx b/web/source/settings/views/admin/http-header-permissions/overview.tsx new file mode 100644 index 000000000..7735e624e --- /dev/null +++ b/web/source/settings/views/admin/http-header-permissions/overview.tsx @@ -0,0 +1,169 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ + +import React, { useMemo } from "react"; +import { useGetHeaderAllowsQuery, useGetHeaderBlocksQuery } from "../../../lib/query/admin/http-header-permissions"; +import { NoArg } from "../../../lib/types/query"; +import { PageableList } from "../../../components/pageable-list"; +import { HeaderPermission } from "../../../lib/types/http-header-permissions"; +import { useLocation, useParams } from "wouter"; +import { PermType } from "../../../lib/types/perm"; +import { FetchBaseQueryError } from "@reduxjs/toolkit/query"; +import { SerializedError } from "@reduxjs/toolkit"; +import HeaderPermCreateForm from "./create"; + +export default function HeaderPermsOverview() { + const [ location, setLocation ] = useLocation(); + + // Parse perm type from routing params. + let params = useParams(); + if (params.permType !== "blocks" && params.permType !== "allows") { + throw "unrecognized perm type " + params.permType; + } + const permType = useMemo(() => { + return params.permType?.slice(0, -1) as PermType; + }, [params]); + + // Uppercase first letter of given permType. + const permTypeUpper = useMemo(() => { + return permType.charAt(0).toUpperCase() + permType.slice(1); + }, [permType]); + + // Fetch desired perms, skipping + // the ones we don't want. + const { + data: blocks, + isLoading: isLoadingBlocks, + isFetching: isFetchingBlocks, + isSuccess: isSuccessBlocks, + isError: isErrorBlocks, + error: errorBlocks + } = useGetHeaderBlocksQuery(NoArg, { skip: permType !== "block" }); + + const { + data: allows, + isLoading: isLoadingAllows, + isFetching: isFetchingAllows, + isSuccess: isSuccessAllows, + isError: isErrorAllows, + error: errorAllows + } = useGetHeaderAllowsQuery(NoArg, { skip: permType !== "allow" }); + + const itemToEntry = (perm: HeaderPermission) => { + return ( + <dl + key={perm.id} + className="entry spanlink" + onClick={() => { + // When clicking on a header perm, + // go to the detail view for perm. + setLocation(`/${permType}s/${perm.id}`, { + // Store the back location in + // history so the detail view + // can use it to return here. + state: { backLocation: location } + }); + }} + role="link" + tabIndex={0} + > + <dt>{perm.header}</dt> + <dd>{perm.regex}</dd> + </dl> + ); + }; + + const emptyMessage = ( + <div className="info"> + <i className="fa fa-fw fa-info-circle" aria-hidden="true"></i> + <b> + No HTTP header {permType}s exist yet. + You can create one using the form below. + </b> + </div> + ); + + let isLoading: boolean; + let isFetching: boolean; + let isSuccess: boolean; + let isError: boolean; + let error: FetchBaseQueryError | SerializedError | undefined; + let items: HeaderPermission[] | undefined; + + if (permType === "block") { + isLoading = isLoadingBlocks; + isFetching = isFetchingBlocks; + isSuccess = isSuccessBlocks; + isError = isErrorBlocks; + error = errorBlocks; + items = blocks; + } else { + isLoading = isLoadingAllows; + isFetching = isFetchingAllows; + isSuccess = isSuccessAllows; + isError = isErrorAllows; + error = errorAllows; + items = allows; + } + + return ( + <div className="http-header-permissions"> + <div className="form-section-docs"> + <h1>HTTP Header {permTypeUpper}s</h1> + <p> + On this page, you can view, create, and remove HTTP header {permType} entries, + <br/> + Blocks and allows have different effects depending on the value you've set + for <code>advanced-header-filter-mode</code> in your instance configuration. + <br/> + { permType === "block" && <> + <strong> + When running in <code>block</code> mode, be very careful when creating + your value regexes, as a too-broad match can cause your instance to + deny all requests, locking you out of this settings panel. + </strong> + <br/> + If you do this by accident, you can fix it by stopping your instance, + changing <code>advanced-header-filter-mode</code> to an empty string + (disabled), starting your instance again, and removing the block. + </> } + </p> + <a + href="https://docs.gotosocial.org/en/latest/admin/request_filtering_modes/" + target="_blank" + className="docslink" + rel="noreferrer" + > + Learn more about HTTP request filtering (opens in a new tab) + </a> + </div> + <PageableList + isLoading={isLoading} + isFetching={isFetching} + isSuccess={isSuccess} + isError={isError} + error={error} + items={items} + itemToEntry={itemToEntry} + emptyMessage={emptyMessage} + /> + <HeaderPermCreateForm permType={permType} /> + </div> + ); +} |