/*
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 { replaceCacheOnMutation } from "../../query-modifiers";
import { gtsApi } from "../../gts-api";
import {
type DomainPerm,
type ImportDomainPermsParams,
type MappedDomainPerms,
isDomainPermInternalKey,
} from "../../../types/domain-permission";
import { listToKeyedObject } from "../../transforms";
/**
* Builds up a map function that can be applied to a
* list of DomainPermission entries in order to normalize
* them before submission to the API.
* @param formData
* @returns
*/
function importEntriesProcessor(formData: ImportDomainPermsParams): (_entry: DomainPerm) => DomainPerm {
let processingFuncs: { (_entry: DomainPerm): void; }[] = [];
// Override each obfuscate entry if necessary.
if (formData.obfuscate !== undefined) {
const obfuscateEntry = (entry: DomainPerm) => {
entry.obfuscate = formData.obfuscate;
};
processingFuncs.push(obfuscateEntry);
}
// Check whether we need to append or replace
// private_comment and public_comment.
["private_comment","public_comment"].forEach((commentType) => {
let text = formData.commentType?.trim();
if (!text) {
return;
}
switch(formData[`${commentType}_behavior`]) {
case "append":
const appendComment = (entry: DomainPerm) => {
if (entry.commentType == undefined) {
entry.commentType = text;
} else {
entry.commentType = [entry.commentType, text].join("\n");
}
};
processingFuncs.push(appendComment);
break;
case "replace":
const replaceComment = (entry: DomainPerm) => {
entry.commentType = text;
};
processingFuncs.push(replaceComment);
break;
}
});
return function process(entry) {
// Call all the assembled processing functions.
processingFuncs.forEach((f) => f(entry));
// Unset all internal processing keys
// and any undefined keys on this entry.
Object.entries(entry).forEach(([key, val]: [keyof DomainPerm, any]) => {
if (val == undefined || isDomainPermInternalKey(key)) {
delete entry[key];
}
});
return entry;
};
}
const extended = gtsApi.injectEndpoints({
endpoints: (build) => ({
importDomainPerms: build.mutation({
query: (formData) => {
// Add/replace comments, remove internal keys.
const process = importEntriesProcessor(formData);
const domains = formData.domains.map(process);
return {
method: "POST",
url: `/api/v1/admin/domain_${formData.permType}s?import=true`,
asForm: true,
discardEmpty: true,
body: {
import: true,
domains: new Blob(
[JSON.stringify(domains)],
{ type: "application/json" },
),
}
};
},
transformResponse: listToKeyedObject("domain"),
...replaceCacheOnMutation((formData: ImportDomainPermsParams) => {
// Query names for blocks and allows are like
// `domainBlocks` and `domainAllows`, so we need
// to convert `block` -> `Block` or `allow` -> `Allow`
// to do proper cache invalidation.
const permType =
formData.permType.charAt(0).toUpperCase() +
formData.permType.slice(1);
return `domain${permType}s`;
}),
})
})
});
/**
* POST domain permissions to /api/v1/admin/domain_{permType}s.
* Returns the newly created permissions.
*/
const useImportDomainPermsMutation = extended.useImportDomainPermsMutation;
export {
useImportDomainPermsMutation,
};