/* 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 from "react"; import { useMemo } from "react"; import { useLocation } from "wouter"; import { useTextInput, useBoolInput } from "../../lib/form"; import useFormSubmit from "../../lib/form/submit"; import { TextInput, Checkbox, TextArea } from "../../components/form/inputs"; import Loading from "../../components/loading"; import BackButton from "../../components/back-button"; import MutationButton from "../../components/form/mutation-button"; import { useDomainAllowsQuery, useDomainBlocksQuery } from "../../lib/query/admin/domain-permissions/get"; import { useAddDomainAllowMutation, useAddDomainBlockMutation, useRemoveDomainAllowMutation, useRemoveDomainBlockMutation } from "../../lib/query/admin/domain-permissions/update"; import { DomainPerm, PermType } from "../../lib/types/domain-permission"; import { NoArg } from "../../lib/types/query"; import { Error } from "../../components/error"; export interface DomainPermDetailProps { baseUrl: string; permType: PermType; domain: string; } export default function DomainPermDetail({ baseUrl, permType, domain }: DomainPermDetailProps) { const { data: domainBlocks = {}, isLoading: isLoadingDomainBlocks } = useDomainBlocksQuery(NoArg, { skip: permType !== "block" }); const { data: domainAllows = {}, isLoading: isLoadingDomainAllows } = useDomainAllowsQuery(NoArg, { skip: permType !== "allow" }); let isLoading; switch (permType) { case "block": isLoading = isLoadingDomainBlocks; break; case "allow": isLoading = isLoadingDomainAllows; break; default: throw "perm type unknown"; } if (domain == "view") { // Retrieve domain from form field submission. domain = (new URL(document.location.toString())).searchParams.get("domain")?? "unknown"; } if (domain == "unknown") { throw "unknown domain"; } // Normalize / decode domain (it may be URL-encoded). domain = decodeURIComponent(domain); // Check if we already have a perm of the desired type for this domain. const existingPerm: DomainPerm | undefined = useMemo(() => { if (permType == "block") { return domainBlocks[domain]; } else { return domainAllows[domain]; } }, [domainBlocks, domainAllows, domain, permType]); let infoContent: React.JSX.Element; if (isLoading) { infoContent = ; } else if (existingPerm == undefined) { infoContent = No stored {permType} yet, you can add one below:; } else { infoContent = (
Editing domain permissions isn't implemented yet, check here for progress
); } return (

Domain {permType} for: {domain}

{infoContent}
); } interface DomainPermFormProps { defaultDomain: string; perm?: DomainPerm; permType: PermType; baseUrl: string; } function DomainPermForm({ defaultDomain, perm, permType, baseUrl }: DomainPermFormProps) { const isExistingPerm = perm !== undefined; const disabledForm = isExistingPerm ? { disabled: true, title: "Domain permissions currently cannot be edited." } : { disabled: false, title: "", }; const form = { domain: useTextInput("domain", { source: perm, defaultValue: defaultDomain }), obfuscate: useBoolInput("obfuscate", { source: perm }), commentPrivate: useTextInput("private_comment", { source: perm }), commentPublic: useTextInput("public_comment", { source: perm }) }; // Check which perm type we're meant to be handling // here, and use appropriate mutations and results. // We can't call these hooks conditionally because // react is like "weh" (mood), but we can decide // which ones to use conditionally. const [ addBlock, addBlockResult ] = useAddDomainBlockMutation(); const [ removeBlock, removeBlockResult] = useRemoveDomainBlockMutation({ fixedCacheKey: perm?.id }); const [ addAllow, addAllowResult ] = useAddDomainAllowMutation(); const [ removeAllow, removeAllowResult ] = useRemoveDomainAllowMutation({ fixedCacheKey: perm?.id }); const [ addTrigger, addResult, removeTrigger, removeResult, ] = useMemo(() => { return permType == "block" ? [ addBlock, addBlockResult, removeBlock, removeBlockResult, ] : [ addAllow, addAllowResult, removeAllow, removeAllowResult, ]; }, [permType, addBlock, addBlockResult, removeBlock, removeBlockResult, addAllow, addAllowResult, removeAllow, removeAllowResult, ]); // Use appropriate submission params for this permType. const [submitForm, submitFormResult] = useFormSubmit(form, [addTrigger, addResult], { changedOnly: false }); // Uppercase first letter of given permType. const permTypeUpper = useMemo(() => { return permType.charAt(0).toUpperCase() + permType.slice(1); }, [permType]); const [location, setLocation] = useLocation(); function verifyUrlThenSubmit(e) { // Adding a new domain permissions happens on a url like // "/settings/admin/domain-permissions/:permType/domain.com", // but if domain input changes, that doesn't match anymore // and causes issues later on so, before submitting the form, // silently change url, and THEN submit. let correctUrl = `${baseUrl}/${form.domain.value}`; if (location != correctUrl) { setLocation(correctUrl); } return submitForm(e); } return (