mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 01:12:56 +03:00
console: remove allow list feature flag
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5889 GitOrigin-RevId: b9a3bab2bd83edb94137603850b405df1766e43b
This commit is contained in:
parent
30bc2185e6
commit
f34bd93e9c
@ -1,20 +1,12 @@
|
||||
import React from 'react';
|
||||
import { Link, RouteComponentProps } from 'react-router';
|
||||
import { canAccessSecuritySettings } from '@/utils/permissions';
|
||||
import {
|
||||
availableFeatureFlagIds,
|
||||
useIsFeatureFlagEnabled,
|
||||
} from '@/features/FeatureFlags';
|
||||
|
||||
type TopNavProps = {
|
||||
location: RouteComponentProps<unknown, unknown>['location'];
|
||||
};
|
||||
|
||||
const TopNav: React.FC<TopNavProps> = ({ location }) => {
|
||||
const { enabled: allowListEnabled } = useIsFeatureFlagEnabled(
|
||||
availableFeatureFlagIds.allowListId
|
||||
);
|
||||
|
||||
const sectionsData = [
|
||||
[
|
||||
{
|
||||
@ -31,16 +23,12 @@ const TopNav: React.FC<TopNavProps> = ({ location }) => {
|
||||
},
|
||||
],
|
||||
[
|
||||
...(allowListEnabled
|
||||
? [
|
||||
{
|
||||
key: 'allow-list',
|
||||
link: '/api/allow-list',
|
||||
dataTestVal: 'allow-list',
|
||||
title: 'Allow List',
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
key: 'allow-list',
|
||||
link: '/api/allow-list',
|
||||
dataTestVal: 'allow-list',
|
||||
title: 'Allow List',
|
||||
},
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -1,169 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import AceEditor from 'react-ace';
|
||||
import { isConsoleError } from '@/components/Common/utils/jsUtils';
|
||||
|
||||
import ExpandableEditor from '../../../Common/Layout/ExpandableEditor/Editor';
|
||||
import Tooltip from '../../../Common/Tooltip/Tooltip';
|
||||
|
||||
import { readFile, parseQueryString, renameDuplicates } from './utils';
|
||||
import { showErrorNotification } from '../../Common/Notification';
|
||||
import { addAllowedQueries } from '../../../../metadata/actions';
|
||||
import { allowedQueriesCollection } from '../../../../metadata/utils';
|
||||
import { AllowedQueriesCollection } from '../../../../metadata/reducer';
|
||||
import { Dispatch } from '../../../../types';
|
||||
import { inputStyles } from '../constants';
|
||||
|
||||
const defaultManualQuery: AllowedQueriesCollection = {
|
||||
name: '',
|
||||
query: '',
|
||||
collection: allowedQueriesCollection,
|
||||
};
|
||||
|
||||
type AddAllowedQueryProps = {
|
||||
dispatch: Dispatch;
|
||||
allowedQueries: AllowedQueriesCollection[];
|
||||
};
|
||||
|
||||
const AddAllowedQuery: React.FC<AddAllowedQueryProps> = props => {
|
||||
const { dispatch, allowedQueries } = props;
|
||||
|
||||
const [manualQuery, setManualQuery] =
|
||||
useState<AllowedQueriesCollection>(defaultManualQuery);
|
||||
const [graphqlFile, setGraphqlFile] = useState<File | null>(null);
|
||||
|
||||
const handleManualCollapse = () => {
|
||||
setManualQuery(defaultManualQuery);
|
||||
};
|
||||
|
||||
const handleManualSubmit = (toggle: () => void) => {
|
||||
dispatch(addAllowedQueries([manualQuery], toggle));
|
||||
};
|
||||
|
||||
const handleFileUploadCollapse = () => {};
|
||||
|
||||
const handleFileUploadSubmit = (toggle: () => void) => {
|
||||
const addFileQueries = (content: string) => {
|
||||
try {
|
||||
const fileQueries = parseQueryString(content);
|
||||
const updatedQueries = renameDuplicates(fileQueries, allowedQueries);
|
||||
dispatch(addAllowedQueries(updatedQueries, toggle));
|
||||
} catch (error) {
|
||||
if (isConsoleError(error)) {
|
||||
dispatch(
|
||||
showErrorNotification('Uploading operations failed', error.message)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
readFile(graphqlFile, addFileQueries);
|
||||
};
|
||||
|
||||
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setManualQuery({
|
||||
...manualQuery,
|
||||
name: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
const handleQueryChange = (val: string) => {
|
||||
setManualQuery({
|
||||
...manualQuery,
|
||||
query: val,
|
||||
});
|
||||
};
|
||||
|
||||
const manualQueryInput = () => (
|
||||
<div>
|
||||
<div>
|
||||
<div className="mb-sm">
|
||||
<b>Query name:</b>
|
||||
<Tooltip
|
||||
message="This is an identifier for the query in the collection.
|
||||
This should be unique in the collection and can be different from the operation name of the query."
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className={`${inputStyles} inline-block`}
|
||||
placeholder="operation_name"
|
||||
value={manualQuery.name}
|
||||
onChange={handleNameChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-md">
|
||||
<div>
|
||||
<div className="mb-sm">
|
||||
<b>Operation:</b>
|
||||
</div>
|
||||
<AceEditor
|
||||
data-test="allowed_operation_add"
|
||||
mode="graphql"
|
||||
theme="github"
|
||||
name="allowed_operation_add"
|
||||
value={manualQuery.query}
|
||||
minLines={8}
|
||||
maxLines={100}
|
||||
width="100%"
|
||||
showPrintMargin={false}
|
||||
onChange={handleQueryChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const handleFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const files = e.target.files;
|
||||
setGraphqlFile(files![0]);
|
||||
};
|
||||
|
||||
const fileUploadInput = () => (
|
||||
<div>
|
||||
<div className="mb-sm">
|
||||
<b>Graphql File:</b>
|
||||
<Tooltip message=".graphql file with operations" />
|
||||
</div>
|
||||
<input
|
||||
type="file"
|
||||
className={`${inputStyles} inline-block`}
|
||||
onChange={handleFileUpload}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4 className="text-lg font-bold pb-sm">
|
||||
Add new operations to allow-list
|
||||
</h4>
|
||||
<div className="px-sm">
|
||||
<div>
|
||||
<ExpandableEditor
|
||||
expandButtonText="Add operation manually"
|
||||
editorExpanded={manualQueryInput}
|
||||
collapseCallback={handleManualCollapse}
|
||||
property="add-allowed-operation"
|
||||
service="add-allowed-operation"
|
||||
saveButtonText="Add"
|
||||
saveFunc={handleManualSubmit}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-md">OR</div>
|
||||
<div className="mt-md">
|
||||
<ExpandableEditor
|
||||
expandButtonText="Upload graphql file"
|
||||
editorExpanded={fileUploadInput}
|
||||
collapseCallback={handleFileUploadCollapse}
|
||||
property="upload-allowed-operations"
|
||||
service="upload-allowed-operations"
|
||||
saveButtonText="Upload"
|
||||
saveFunc={handleFileUploadSubmit}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddAllowedQuery;
|
@ -1,67 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { browserHistory } from 'react-router';
|
||||
import {
|
||||
availableFeatureFlagIds,
|
||||
FeatureFlagToast,
|
||||
useIsFeatureFlagEnabled,
|
||||
} from '@/features/FeatureFlags';
|
||||
|
||||
import AllowedQueriesNotes from './AllowedQueriesNotes';
|
||||
import AddAllowedQuery from './AddAllowedQuery';
|
||||
import AllowedQueriesList from './AllowedQueriesList';
|
||||
|
||||
import { getAllowedQueries } from '../../../../metadata/selector';
|
||||
import { Dispatch, ReduxState } from '../../../../types';
|
||||
import { mapDispatchToPropsEmpty } from '../../../Common/utils/reactUtils';
|
||||
import { AllowedQueriesCollection } from '../../../../metadata/reducer';
|
||||
|
||||
interface Props {
|
||||
dispatch: Dispatch;
|
||||
allowedQueries: AllowedQueriesCollection[];
|
||||
}
|
||||
|
||||
const AllowedQueries: React.FC<Props> = props => {
|
||||
const { dispatch, allowedQueries } = props;
|
||||
|
||||
const { enabled: featureFlagEnabled } = useIsFeatureFlagEnabled(
|
||||
availableFeatureFlagIds.allowListId
|
||||
);
|
||||
|
||||
if (featureFlagEnabled) {
|
||||
browserHistory.push('/api/allow-list');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="clear-both pl-md pt-md mb-md">
|
||||
<div>
|
||||
<h2 className="text-xl font-bold">Allow List</h2>
|
||||
<div className="mt-md w-1/2">
|
||||
<AllowedQueriesNotes />
|
||||
<hr className="my-md" />
|
||||
<AddAllowedQuery
|
||||
dispatch={dispatch}
|
||||
allowedQueries={allowedQueries}
|
||||
/>
|
||||
<hr className="my-md" />
|
||||
<AllowedQueriesList
|
||||
dispatch={dispatch}
|
||||
allowedQueries={allowedQueries}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FeatureFlagToast flagId={availableFeatureFlagIds.allowListId} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state: ReduxState) => {
|
||||
return {
|
||||
allowedQueries: getAllowedQueries(state),
|
||||
};
|
||||
};
|
||||
|
||||
const allowedQueriesConnector = (connect: any) =>
|
||||
connect(mapStateToProps, mapDispatchToPropsEmpty)(AllowedQueries);
|
||||
|
||||
export default allowedQueriesConnector;
|
@ -1,184 +0,0 @@
|
||||
import React, { useState } from 'react';
|
||||
import AceEditor from 'react-ace';
|
||||
|
||||
import { Button } from '@/new-components/Button';
|
||||
import ExpandableEditor from '../../../Common/Layout/ExpandableEditor/Editor';
|
||||
|
||||
import { getConfirmation } from '../../../Common/utils/jsUtils';
|
||||
import {
|
||||
updateAllowedQuery,
|
||||
deleteAllowedQuery,
|
||||
deleteAllowList,
|
||||
} from '../../../../metadata/actions';
|
||||
import { AllowedQueriesCollection } from '../../../../metadata/reducer';
|
||||
import { Dispatch } from '../../../../types';
|
||||
import { getCollectionNames, checkLastQuery } from './utils';
|
||||
import Tooltip from '../../../Common/Tooltip/Tooltip';
|
||||
import { inputStyles } from '../constants';
|
||||
|
||||
type AllowedQueriesListProps = {
|
||||
dispatch: Dispatch;
|
||||
allowedQueries: AllowedQueriesCollection[];
|
||||
};
|
||||
|
||||
type ModifiedQuery = Record<string, AllowedQueriesCollection>;
|
||||
|
||||
const AllowedQueriesList: React.FC<AllowedQueriesListProps> = props => {
|
||||
const [modifiedQueries, setModifiedQueries] = useState<ModifiedQuery>({});
|
||||
const { allowedQueries, dispatch } = props;
|
||||
|
||||
const getQueryList = () => {
|
||||
if (allowedQueries.length === 0) {
|
||||
return <div>No operations in allow-list yet</div>;
|
||||
}
|
||||
|
||||
return allowedQueries.map((query, i) => {
|
||||
const queryName = query.name;
|
||||
const collectionName = query.collection;
|
||||
const queryId = `${queryName}_${collectionName}_${i}`;
|
||||
|
||||
const collapsedLabel = () => (
|
||||
<div>
|
||||
<b>{queryName} </b>
|
||||
<i>- {collectionName}</i>
|
||||
</div>
|
||||
);
|
||||
|
||||
const expandedLabel = collapsedLabel;
|
||||
|
||||
const queryEditorExpanded = () => {
|
||||
const modifiedQuery = modifiedQueries[queryId] || { ...query };
|
||||
|
||||
const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const newModifiedQueries = { ...modifiedQueries };
|
||||
newModifiedQueries[queryId].name = e.target.value;
|
||||
setModifiedQueries(newModifiedQueries);
|
||||
};
|
||||
|
||||
const handleQueryChange = (val: string) => {
|
||||
const newModifiedQueries = { ...modifiedQueries };
|
||||
newModifiedQueries[queryId].query = val;
|
||||
setModifiedQueries(newModifiedQueries);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<div className="mb-md">
|
||||
<b>Query name:</b>
|
||||
<Tooltip
|
||||
message="This is an identifier for the query in the collection.
|
||||
This should be unique in the collection and can be different from the operation name of the query."
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className={`${inputStyles} inline-block`}
|
||||
value={modifiedQuery.name}
|
||||
placeholder="operation_name"
|
||||
onChange={handleNameChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-mb">
|
||||
<div className="mb-md">
|
||||
<b>Operation:</b>
|
||||
</div>
|
||||
<AceEditor
|
||||
data-test="allowed_operation_editor"
|
||||
mode="graphql"
|
||||
theme="github"
|
||||
name="allowed_operation_editor"
|
||||
value={modifiedQuery.query}
|
||||
minLines={8}
|
||||
maxLines={100}
|
||||
width="100%"
|
||||
showPrintMargin={false}
|
||||
onChange={handleQueryChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const editorExpandCallback = () => {
|
||||
const newModifiedQueries = { ...modifiedQueries };
|
||||
newModifiedQueries[queryId] = { ...query };
|
||||
setModifiedQueries(newModifiedQueries);
|
||||
};
|
||||
|
||||
const editorCollapseCallback = () => {
|
||||
const newModifiedQueries = { ...modifiedQueries };
|
||||
delete newModifiedQueries[queryId];
|
||||
setModifiedQueries(newModifiedQueries);
|
||||
};
|
||||
|
||||
const onSubmit = () => {
|
||||
dispatch(
|
||||
updateAllowedQuery(
|
||||
queryName,
|
||||
modifiedQueries[queryId],
|
||||
collectionName
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
const onDelete = () => {
|
||||
const confirmMessage = `This will delete the operation "${queryName}" from the allow-list`;
|
||||
const isOk = getConfirmation(confirmMessage);
|
||||
if (isOk) {
|
||||
const isLastQuery = checkLastQuery(collectionName, allowedQueries);
|
||||
dispatch(deleteAllowedQuery(queryName, isLastQuery, collectionName));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div key={queryId}>
|
||||
<ExpandableEditor
|
||||
editorExpanded={queryEditorExpanded}
|
||||
property={`query-${i}`}
|
||||
service="modify-allowed-operation"
|
||||
saveFunc={onSubmit}
|
||||
removeFunc={onDelete}
|
||||
collapsedClass="flex"
|
||||
expandedLabel={expandedLabel}
|
||||
collapsedLabel={collapsedLabel}
|
||||
expandCallback={editorExpandCallback}
|
||||
collapseCallback={editorCollapseCallback}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteAll = () => {
|
||||
const confirmMessage =
|
||||
'This will delete all operations from the allow-list';
|
||||
const isOk = getConfirmation(confirmMessage, true);
|
||||
const collectionNames = getCollectionNames(allowedQueries);
|
||||
if (isOk) {
|
||||
dispatch(deleteAllowList(collectionNames));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4 className="text-lg font-bold pb-md">
|
||||
Allow List
|
||||
<span className="pl-md">
|
||||
<Button
|
||||
size="sm"
|
||||
mode="destructive"
|
||||
onClick={handleDeleteAll}
|
||||
disabled={allowedQueries.length === 0}
|
||||
>
|
||||
Delete all
|
||||
</Button>
|
||||
</span>
|
||||
</h4>
|
||||
|
||||
<div className="pl-md">{getQueryList()}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AllowedQueriesList;
|
@ -1,29 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
const AllowedQueriesNotes: React.FC = () => {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
If GraphQL Engine is started with the{' '}
|
||||
<code>HASURA_GRAPHQL_ENABLE_ALLOWLIST</code> env var or the{' '}
|
||||
<code>--enable-allowlist</code> flag set to <i>true</i>, only operations
|
||||
added to the allow-list will be allowed to be executed.
|
||||
<a
|
||||
href="https://hasura.io/docs/latest/graphql/core/deployment/allow-list.html"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<i>(Read more)</i>
|
||||
</a>
|
||||
</div>
|
||||
<div className="mt-md">
|
||||
<b>Notes</b>
|
||||
<div className="pl-lg pt-sm">
|
||||
All allowed operations need to have a unique name for reference
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AllowedQueriesNotes;
|
@ -1,9 +1,5 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
import React from 'react';
|
||||
import {
|
||||
availableFeatureFlagIds,
|
||||
useIsFeatureFlagEnabled,
|
||||
} from '@/features/FeatureFlags';
|
||||
import { Link, RouteComponentProps } from 'react-router';
|
||||
import LeftContainer from '../../Common/Layout/LeftContainer/LeftContainer';
|
||||
import CheckIcon from '../../Common/Icons/Check';
|
||||
@ -48,10 +44,6 @@ interface SectionData {
|
||||
const Sidebar: React.FC<SidebarProps> = ({ location, metadata }) => {
|
||||
const sectionsData: SectionData[] = [];
|
||||
|
||||
const { enabled: newAllowListEnabled } = useIsFeatureFlagEnabled(
|
||||
availableFeatureFlagIds.allowListId
|
||||
);
|
||||
|
||||
sectionsData.push({
|
||||
key: 'actions',
|
||||
link: '/settings/metadata-actions',
|
||||
@ -81,7 +73,7 @@ const Sidebar: React.FC<SidebarProps> = ({ location, metadata }) => {
|
||||
|
||||
sectionsData.push({
|
||||
key: 'allow-list',
|
||||
link: newAllowListEnabled ? '/api/allow-list' : '/settings/allow-list',
|
||||
link: '/api/allow-list',
|
||||
dataTestVal: 'allow-list-link',
|
||||
title: 'Allow List',
|
||||
});
|
||||
|
@ -1,7 +1,6 @@
|
||||
export { default as metadataContainer } from './Container';
|
||||
export { default as metadataOptionsContainer } from './MetadataOptions/MetadataOptions';
|
||||
export { default as metadataStatusContainer } from './MetadataStatus/MetadataStatus';
|
||||
export { default as allowedQueriesContainer } from './AllowedQueries/AllowedQueries';
|
||||
export { default as logoutContainer } from './Logout/Logout';
|
||||
export { default as aboutContainer } from './About/About';
|
||||
export { default as InheritedRolesContainer } from './InheritedRoles/InheritedRoles';
|
||||
|
@ -156,7 +156,7 @@ export const AllowListPermissions: React.FC<AllowListPermissionsTabProps> = ({
|
||||
</div>
|
||||
</td>
|
||||
<td className="group relative text-center p-sm whitespace-nowrap cursor-pointer">
|
||||
{updatingRoles.includes(roleName) ? (
|
||||
{updatingRoles.length > 0 ? (
|
||||
<CgSpinner className={`animate-spin ${'w-5 h-5'}`} />
|
||||
) : (
|
||||
<Switch
|
||||
@ -180,7 +180,7 @@ export const AllowListPermissions: React.FC<AllowListPermissionsTabProps> = ({
|
||||
/>
|
||||
</td>
|
||||
<td className="group relative text-center p-sm whitespace-nowrap cursor-pointer flex items-center justify-center">
|
||||
{updatingRoles.includes(newRole) ? (
|
||||
{updatingRoles.length > 0 ? (
|
||||
<CgSpinner className={`animate-spin ${'w-5 h-5'}`} />
|
||||
) : (
|
||||
<Switch
|
||||
|
@ -21,16 +21,6 @@ export const availableFeatureFlags: FeatureFlagDefinition[] = [
|
||||
defaultValue: false,
|
||||
discussionUrl: '',
|
||||
},
|
||||
{
|
||||
id: allowListId,
|
||||
title: 'New Allow List Manager',
|
||||
description:
|
||||
'Try out the new UI for the Allow List management in the API section.',
|
||||
section: 'api',
|
||||
status: 'alpha',
|
||||
defaultValue: false,
|
||||
discussionUrl: '',
|
||||
},
|
||||
{
|
||||
id: gdcId,
|
||||
title: 'Experimental features for GDC',
|
||||
|
@ -6,10 +6,7 @@ import {
|
||||
FieldWrapper,
|
||||
FieldWrapperPassThroughProps,
|
||||
} from '@/new-components/Form';
|
||||
import {
|
||||
parseQueryString,
|
||||
readFile,
|
||||
} from '@/components/Services/Settings/AllowedQueries/utils';
|
||||
import { parseQueryString, readFile } from './utils';
|
||||
|
||||
export type GraphQLFileUploadProps = FieldWrapperPassThroughProps & {
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { allowedQueriesCollection } from '../../../../metadata/utils';
|
||||
import { renameDuplicates, parseQueryString } from '../AllowedQueries/utils';
|
||||
import { uploadedFileData } from './fixtures/allow-list';
|
||||
import { renameDuplicates, parseQueryString } from './utils';
|
||||
import { uploadedFileData } from './fixtures';
|
||||
|
||||
describe('AllowedQueries_Utils.ts', () => {
|
||||
describe('renameDuplicates', () => {
|
@ -19,7 +19,6 @@ import settingsContainer from './components/Services/Settings/Container';
|
||||
import ApiContainer from './components/Services/ApiExplorer/Container';
|
||||
import metadataOptionsConnector from './components/Services/Settings/MetadataOptions/MetadataOptions';
|
||||
import metadataStatusConnector from './components/Services/Settings/MetadataStatus/MetadataStatus';
|
||||
import allowedQueriesConnector from './components/Services/Settings/AllowedQueries/AllowedQueries';
|
||||
import inheritedRolesConnector from './components/Services/Settings/InheritedRoles/InheritedRoles';
|
||||
import logoutConnector from './components/Services/Settings/Logout/Logout';
|
||||
import aboutConnector from './components/Services/Settings/About/About';
|
||||
@ -150,10 +149,6 @@ const routes = store => {
|
||||
path="metadata-status"
|
||||
component={metadataStatusConnector(connect)}
|
||||
/>
|
||||
<Route
|
||||
path="allow-list"
|
||||
component={allowedQueriesConnector(connect)}
|
||||
/>
|
||||
<Route path="logout" component={logoutConnector(connect)} />
|
||||
<Route path="about" component={aboutConnector(connect)} />
|
||||
<Route path="inherited-roles" component={inheritedRolesConnector} />
|
||||
|
@ -1,97 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AllowedQueries_Utils.ts renameDuplicates should rename duplicate queries 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"name": "getAuthors_1",
|
||||
"query": "query getAuthors {
|
||||
author {
|
||||
id
|
||||
name
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "getAuthors_2",
|
||||
"query": "query getAuthors {
|
||||
author {
|
||||
id
|
||||
name
|
||||
address
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "getAuthors_3",
|
||||
"query": "query getAuthors {
|
||||
author {
|
||||
id
|
||||
name
|
||||
age
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "unnamed",
|
||||
"query": "{
|
||||
student {
|
||||
id
|
||||
name
|
||||
age
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "unnamed_1",
|
||||
"query": "{
|
||||
student {
|
||||
id
|
||||
name
|
||||
roll
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "unnamed_2",
|
||||
"query": "{
|
||||
student {
|
||||
id
|
||||
name
|
||||
address
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "getArticles",
|
||||
"query": "query getArticles {
|
||||
article {
|
||||
id
|
||||
title
|
||||
}
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "getArticle",
|
||||
"query": "query getArticle {
|
||||
article {
|
||||
id
|
||||
title
|
||||
...frag
|
||||
}
|
||||
}
|
||||
|
||||
fragment frag on Starship {
|
||||
name
|
||||
}",
|
||||
},
|
||||
Object {
|
||||
"name": "addArticles",
|
||||
"query": "mutation addArticles {
|
||||
insert_articles {
|
||||
id
|
||||
title
|
||||
}
|
||||
}",
|
||||
},
|
||||
]
|
||||
`;
|
@ -1,94 +0,0 @@
|
||||
export const uploadedFileData = `# will be ignored by the allow-list
|
||||
type Starship {
|
||||
id: ID!
|
||||
name: String!
|
||||
length(unit: LengthUnit = METER): Float
|
||||
}
|
||||
|
||||
# will be ignored by the allow-list
|
||||
scalar parsec
|
||||
|
||||
# will be ignored by the allow-list
|
||||
enum Episode {
|
||||
NEWHOPE
|
||||
EMPIRE
|
||||
JEDI
|
||||
}
|
||||
|
||||
# will be stored in the allow-list
|
||||
query getAuthors{
|
||||
author {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
|
||||
query getAuthors{
|
||||
author {
|
||||
id
|
||||
name
|
||||
address
|
||||
}
|
||||
}
|
||||
|
||||
query getAuthors{
|
||||
author {
|
||||
id
|
||||
name
|
||||
age
|
||||
}
|
||||
}
|
||||
|
||||
query {
|
||||
student {
|
||||
id
|
||||
name
|
||||
age
|
||||
}
|
||||
}
|
||||
|
||||
query {
|
||||
student {
|
||||
id
|
||||
name
|
||||
roll
|
||||
}
|
||||
}
|
||||
|
||||
query {
|
||||
student {
|
||||
id
|
||||
name
|
||||
address
|
||||
}
|
||||
}
|
||||
|
||||
fragment frag on Starship {
|
||||
name
|
||||
}
|
||||
|
||||
# will be stored in the allow-list
|
||||
query getArticles {
|
||||
article {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
|
||||
# will be stored in the allow-list after patching in the fragment
|
||||
query getArticle {
|
||||
article {
|
||||
id
|
||||
title
|
||||
...frag
|
||||
}
|
||||
}
|
||||
|
||||
# will be stored in the allow-list
|
||||
mutation addArticles {
|
||||
insert_articles {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
`;
|
@ -1,20 +0,0 @@
|
||||
import { allowedQueriesCollection } from '../../../../metadata/utils';
|
||||
import { renameDuplicates, parseQueryString } from '../AllowedQueries/utils';
|
||||
import { uploadedFileData } from './fixtures/allow-list';
|
||||
|
||||
describe('AllowedQueries_Utils.ts', () => {
|
||||
describe('renameDuplicates', () => {
|
||||
it('should rename duplicate queries', () => {
|
||||
const allowedListQueries = [
|
||||
{
|
||||
name: 'getAuthors',
|
||||
query: 'query getAuthors { author {id name} }',
|
||||
collection: allowedQueriesCollection,
|
||||
},
|
||||
];
|
||||
const fileQueries = parseQueryString(uploadedFileData);
|
||||
const updatedQueries = renameDuplicates(fileQueries, allowedListQueries);
|
||||
expect(updatedQueries).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user