ToolJet/frontend/src/_ui/OpenAPI/index.js

254 lines
7.2 KiB
JavaScript
Raw Normal View History

Feature: OpenApi import plugin (#2728) * Initialized OpenApi plugin * Added definition field to manifest file * Added an openapi parser * Implemented JSON/YAML resolver - Removed swagger parser lib - Added a field for choosing definition format type - Implemented a resolver for resolving $ref * Implemented a basic operations drop down from spec paths * Added params and body ui * Now, can view general parameters and servers * Added an option to override general params - Resolved a bug * Implemented basic openapi plugin - Added got lib - Tested basic queries * Added one more method * Resolved a common bug * Working on Parsing definition from datasource modal - Created new form component for openapi - Populated select array from security array * Added ui for authentication * Added bearer & basic plugin code * Resolved some ui issues of Apikeys auth option * Added apikey auth * Resolved an issue - Also replaced validate btn with auto validation - Now spec will be added to db from data-source modal * Added error text to show validation error * Now spec will load from props for query manager * Added some padding to operation description * Added ui for openapi oauth2 auth * Implemented oauth2 * Fixed a state issue with a temporary hack * Now we can show multiple same auth types * added the icon * Resolved a bug & improved multiple apikeys process * Resolved some realtime parsing error * Resolved a bug from options fn * Resolved PR changes * Updated documentation with brief details about the open API plugin * Removed unwanted package * Changed if-else to switch * Code changes * added setLoadingSpec fn to catch section * Solved typos and error in doc * Resolved dropdown issue * Resolved a bug * updated openapi icon
2022-04-26 08:44:12 +00:00
import React, { useEffect, useState } from 'react';
import Select from '@/_ui/Select';
import Textarea from '@/_ui/Textarea';
import { openapiService } from '@/_services';
import OpenapiAuth from './OpenapiAuth';
const OpenApi = ({
optionchanged,
format,
definition,
auth_type,
auth_key,
bearer_token,
username,
password,
api_keys,
access_token_url,
client_id,
client_secret,
client_auth,
custom_auth_params,
custom_query_params,
add_token_to,
header_prefix,
grant_type,
scopes,
auth_url,
[Feature] :: Global datasources (#5504) * add: columns and migrations for data queries and sources * add: migrations for app environments * fix: datasources and queries api * fix: import apis * add: radixui colors * create: global datasource page * fix: version creation not including global datasources queries * fix: version deletion failure * fix: ui and other bugs * add: check for abilities on global ds * fix: bugs * fix: existing test cases * fix: migration and bugs * fix: rest api oauthorize bugs * hide: add button for local ds * fix: query bugs * fix: new organization environment creation * fix: local ds label showing for new apps * fix: on page load queries for preview app and published app * fix: import bugs from v1 * fix: merge conflicts * fix: import apis * fix: apss with mulit envs * fix: ui bugs * fix: environments not being created on db:seed * fix: ui bugs * fix: route settings for global datasources * fix: customer dashboard template * fix: local ds queries not being saved * fix: runpy issues * changes: ui * fix: migration issues * fix: ui * hide datasources when no local datasources * fix: test cases * fix: unit test cases and global queries on app import/export * cleanup * add: package-lock file * undo: migration rename * cleanup * fix: ui bugs * migration fixes * fix: dark mode issues * fix: change datasource failing on query create mode * fix: workspace selector issues * fix: clickoutside for change scope option * migration changes * fix: open api issue * reverting configs changes * [Fix] Global datasources & Environment Id issue (#5830) * fix: oauth env id issue * code changes --------- Co-authored-by: gsmithun4 <[email protected]> Co-authored-by: Muhsin Shah <[email protected]>
2023-03-24 16:11:21 +00:00
spec,
Feature: OpenApi import plugin (#2728) * Initialized OpenApi plugin * Added definition field to manifest file * Added an openapi parser * Implemented JSON/YAML resolver - Removed swagger parser lib - Added a field for choosing definition format type - Implemented a resolver for resolving $ref * Implemented a basic operations drop down from spec paths * Added params and body ui * Now, can view general parameters and servers * Added an option to override general params - Resolved a bug * Implemented basic openapi plugin - Added got lib - Tested basic queries * Added one more method * Resolved a common bug * Working on Parsing definition from datasource modal - Created new form component for openapi - Populated select array from security array * Added ui for authentication * Added bearer & basic plugin code * Resolved some ui issues of Apikeys auth option * Added apikey auth * Resolved an issue - Also replaced validate btn with auto validation - Now spec will be added to db from data-source modal * Added error text to show validation error * Now spec will load from props for query manager * Added some padding to operation description * Added ui for openapi oauth2 auth * Implemented oauth2 * Fixed a state issue with a temporary hack * Now we can show multiple same auth types * added the icon * Resolved a bug & improved multiple apikeys process * Resolved some realtime parsing error * Resolved a bug from options fn * Resolved PR changes * Updated documentation with brief details about the open API plugin * Removed unwanted package * Changed if-else to switch * Code changes * added setLoadingSpec fn to catch section * Solved typos and error in doc * Resolved dropdown issue * Resolved a bug * updated openapi icon
2022-04-26 08:44:12 +00:00
}) => {
const [securities, setSecurities] = useState([]);
const [loadingSpec, setLoadingSpec] = useState(false);
const [selectedAuth, setSelectedAuth] = useState();
const [validationError, setValidationError] = useState();
useEffect(() => {
validateDef();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [definition, format]);
useEffect(() => {
auth_key && getSelectedAuth();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [auth_key, securities]);
[Feature] :: Global datasources (#5504) * add: columns and migrations for data queries and sources * add: migrations for app environments * fix: datasources and queries api * fix: import apis * add: radixui colors * create: global datasource page * fix: version creation not including global datasources queries * fix: version deletion failure * fix: ui and other bugs * add: check for abilities on global ds * fix: bugs * fix: existing test cases * fix: migration and bugs * fix: rest api oauthorize bugs * hide: add button for local ds * fix: query bugs * fix: new organization environment creation * fix: local ds label showing for new apps * fix: on page load queries for preview app and published app * fix: import bugs from v1 * fix: merge conflicts * fix: import apis * fix: apss with mulit envs * fix: ui bugs * fix: environments not being created on db:seed * fix: ui bugs * fix: route settings for global datasources * fix: customer dashboard template * fix: local ds queries not being saved * fix: runpy issues * changes: ui * fix: migration issues * fix: ui * hide datasources when no local datasources * fix: test cases * fix: unit test cases and global queries on app import/export * cleanup * add: package-lock file * undo: migration rename * cleanup * fix: ui bugs * migration fixes * fix: dark mode issues * fix: change datasource failing on query create mode * fix: workspace selector issues * fix: clickoutside for change scope option * migration changes * fix: open api issue * reverting configs changes * [Fix] Global datasources & Environment Id issue (#5830) * fix: oauth env id issue * code changes --------- Co-authored-by: gsmithun4 <[email protected]> Co-authored-by: Muhsin Shah <[email protected]>
2023-03-24 16:11:21 +00:00
useEffect(() => {
spec && setSecurities(resolveSecurities(spec));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [spec]);
Feature: OpenApi import plugin (#2728) * Initialized OpenApi plugin * Added definition field to manifest file * Added an openapi parser * Implemented JSON/YAML resolver - Removed swagger parser lib - Added a field for choosing definition format type - Implemented a resolver for resolving $ref * Implemented a basic operations drop down from spec paths * Added params and body ui * Now, can view general parameters and servers * Added an option to override general params - Resolved a bug * Implemented basic openapi plugin - Added got lib - Tested basic queries * Added one more method * Resolved a common bug * Working on Parsing definition from datasource modal - Created new form component for openapi - Populated select array from security array * Added ui for authentication * Added bearer & basic plugin code * Resolved some ui issues of Apikeys auth option * Added apikey auth * Resolved an issue - Also replaced validate btn with auto validation - Now spec will be added to db from data-source modal * Added error text to show validation error * Now spec will load from props for query manager * Added some padding to operation description * Added ui for openapi oauth2 auth * Implemented oauth2 * Fixed a state issue with a temporary hack * Now we can show multiple same auth types * added the icon * Resolved a bug & improved multiple apikeys process * Resolved some realtime parsing error * Resolved a bug from options fn * Resolved PR changes * Updated documentation with brief details about the open API plugin * Removed unwanted package * Changed if-else to switch * Code changes * added setLoadingSpec fn to catch section * Solved typos and error in doc * Resolved dropdown issue * Resolved a bug * updated openapi icon
2022-04-26 08:44:12 +00:00
const validateDef = () => {
if (definition) {
setLoadingSpec(true);
setValidationError(null);
openapiService
.parseOpenapiSpec(definition, format)
.then((result) => {
optionchanged('spec', result);
setLoadingSpec(false);
})
.catch((err) => {
setValidationError(err?.message ?? 'Enter valid definition');
setLoadingSpec(false);
console.log(err);
});
}
};
const getCurrentKey = (key, parentKey) => {
let currentValue;
if (!api_keys) return '';
api_keys.map((item) => {
const itemKey = item['parent_key'] ?? item.parentKey;
if (parentKey && itemKey === parentKey) {
item.fields.map((field) => {
if (field.key === key) {
currentValue = field.value;
return;
}
});
if (currentValue) return;
}
if (item.key === key) {
currentValue = item.value;
return;
}
});
return currentValue;
};
const resolveSecurities = (spec) => {
const authArray = [];
const ApiKeys = [];
const securities = spec['security'];
if (securities) {
const scheme = spec?.components?.securitySchemes;
securities.map((security) => {
const authNames = Object.keys(security);
if (authNames.length > 1) {
const authObject = [];
const multipleKeys = { parentKey: authNames[0], fields: [] };
authNames.map((authName, index) => {
const auth = scheme[authName];
if (auth) {
auth['key'] = authName;
authObject.push(auth);
if (auth.type === 'apiKey') {
multipleKeys.fields.push({ ...auth, value: getCurrentKey(auth.key, authNames[0]) });
if (authNames.length == index + 1) ApiKeys.push(multipleKeys);
}
}
});
authObject.length > 0 && authArray.push(authObject);
} else {
const authName = authNames[0];
const auth = scheme[authName];
if (auth) {
auth['key'] = authName;
if (auth.type === 'apiKey') {
const apiKeyObj = { ...auth, value: getCurrentKey(auth.key) };
ApiKeys.push(apiKeyObj);
} else if (auth.type === 'oauth2') {
const scopes = security[authName];
auth['general_scopes'] = scopes;
}
authArray.push(auth);
}
}
});
}
optionchanged('api_keys', ApiKeys);
return authArray;
};
const resolveAuthTypes = (auth) => {
switch (auth.type) {
case 'http':
return {
name: `${auth.key} (${auth?.scheme?.charAt(0).toUpperCase() + auth?.scheme?.slice(1)})`,
value: auth.key,
};
case 'apiKey':
return { name: `${auth.key} (API Key)`, value: auth.key };
case 'oauth2':
return { name: `${auth.key} (Ouath2)`, value: auth.key };
}
};
const computeAuthOptions = () => {
const options = [];
securities.map((auth) => {
if (Array.isArray(auth)) {
const resolved = resolveAuthTypes(auth[0]);
resolved && options.push(resolved);
} else {
const resolved = resolveAuthTypes(auth);
resolved && options.push(resolved);
}
});
return options;
};
const getSelectedAuth = () => {
securities.map((security) => {
if (Array.isArray(security)) {
if (security[0].key === auth_key) {
optionchanged('auth_type', security[0].scheme ?? security[0].type);
setSelectedAuth(security);
}
} else {
if (security.key === auth_key) {
setSelectedAuth(security);
optionchanged('auth_type', security.scheme ?? security.type);
}
}
});
};
return (
<>
<Select
options={[
{ name: 'JSON', value: 'json' },
{ name: 'YAML', value: 'yaml' },
]}
value={format}
onChange={(value) => optionchanged('format', value)}
width={'100%'}
useMenuPortal={false}
/>
<div className="col-md-12">
<label className="form-label text-muted mt-3">Definition</label>
<Textarea
placehlder="Enter spec definition"
className="form-control"
rows="14"
value={definition}
onChange={(e) => optionchanged('definition', e.target.value)}
/>
</div>
{loadingSpec && (
<div className="p-3">
{!validationError ? (
<>
<div className="spinner-border spinner-border-sm text-azure mx-2" role="status"></div>
Please wait while we are validating the OpenAPI specification.
</>
) : (
<span style={{ color: 'red' }}>{validationError}</span>
)}
</div>
)}
{!loadingSpec && Array.isArray(securities) && securities.length > 0 && (
<>
<div className="col-md-12">
<label className="form-label text-muted mt-3">Authentication</label>
<Select
options={computeAuthOptions()}
value={auth_key}
onChange={(value) => optionchanged('auth_key', value)}
width={'100%'}
useMenuPortal={false}
/>
</div>
<OpenapiAuth
username={username}
password={password}
optionchanged={optionchanged}
bearer_token={bearer_token}
authObject={selectedAuth}
api_keys={api_keys}
add_token_to={add_token_to}
header_prefix={header_prefix}
access_token_url={access_token_url}
grant_type={grant_type}
custom_auth_params={custom_auth_params}
custom_query_params={custom_query_params}
client_id={client_id}
client_secret={client_secret}
client_auth={client_auth}
scopes={scopes}
auth_url={auth_url}
auth_type={auth_type}
/>
</>
)}
</>
);
};
export default OpenApi;