diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index efb381f0a..5c026c75f 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -1,6 +1,7 @@ const fs = require('fs-extra'); const axios = require('axios'); const path = require('path'); +const { extractPackageName } = require('dbgate-tools'); const { pluginsdir, datadir } = require('../utility/directories'); const socket = require('../utility/socket'); const requirePlugin = require('../shell/requirePlugin'); @@ -50,7 +51,7 @@ module.exports = { `http://registry.npmjs.com/-/v1/search?text=${encodeURIComponent(filter)}+keywords:dbgateplugin&size=25&from=0` ); const { objects } = resp.data || {}; - return (objects || []).map((x) => x.package); + return (objects || []).map(x => x.package); }, info_meta: 'get', @@ -88,9 +89,7 @@ module.exports = { const files = await fs.readdir(pluginsdir()); const res = []; for (const packageName of files) { - const manifest = await fs - .readFile(path.join(pluginsdir(), packageName, 'package.json')) - .then((x) => JSON.parse(x)); + const manifest = await fs.readFile(path.join(pluginsdir(), packageName, 'package.json')).then(x => JSON.parse(x)); const readmeFile = path.join(pluginsdir(), packageName, 'README.md'); if (await fs.exists(readmeFile)) { manifest.readme = await fs.readFile(readmeFile, { encoding: 'utf-8' }); @@ -131,6 +130,14 @@ module.exports = { return content.commands[command](args); }, + authTypes_meta: 'post', + async authTypes({ engine }) { + const packageName = extractPackageName(engine); + const content = requirePlugin(packageName); + if (!content.driver || content.driver.engine != engine) return null; + return content.driver.getAuthTypes() || null; + }, + async _init() { const installed = await this.installed(); try { @@ -142,7 +149,7 @@ module.exports = { } for (const packageName of preinstallPlugins) { if (this.removedPlugins.includes(packageName)) continue; - if (installed.find((x) => x.name == packageName)) continue; + if (installed.find(x => x.name == packageName)) continue; try { console.log('Preinstalling plugin', packageName); await this.install({ packageName }); diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 59b2328dc..9544c1cd1 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -18,6 +18,12 @@ export interface WriteTableOptions { createIfNotExists?: boolean; } +export interface EngineAuthType { + title: string; + name: string; + disabledFields: string[]; +} + export interface EngineDriver { engine: string; title: string; @@ -44,6 +50,7 @@ export interface EngineDriver { analyseIncremental(pool: any, structure: DatabaseInfo): Promise; dialect: SqlDialect; createDumper(): SqlDumper; + getAuthTypes(): EngineAuthType[]; analyserClass?: any; dumperClass?: any; diff --git a/packages/web/src/modals/ConnectionModal.js b/packages/web/src/modals/ConnectionModal.js index 34ecffc0c..e42881002 100644 --- a/packages/web/src/modals/ConnectionModal.js +++ b/packages/web/src/modals/ConnectionModal.js @@ -8,9 +8,52 @@ import ModalContent from './ModalContent'; import useExtensions from '../utility/useExtensions'; import LoadingInfo from '../widgets/LoadingInfo'; import { FontIcon } from '../icons'; -import { FormProvider } from '../utility/FormProvider'; +import { FormProvider, useForm } from '../utility/FormProvider'; // import FormikForm from '../utility/FormikForm'; +function DriverFields({ extensions }) { + const { values, setFieldValue } = useForm(); + const { authType, engine } = values; + const driver = extensions.drivers.find(x => x.engine == engine); + // const { authTypes } = driver || {}; + const [authTypes, setAuthTypes] = React.useState(null); + const currentAuthType = authTypes && authTypes.find(x => x.name == authType); + + const loadAuthTypes = async () => { + const resp = await axios.post('plugins/auth-types', { engine }); + setAuthTypes(resp.data); + if (resp.data && !currentAuthType) { + setFieldValue('authType', resp.data[0].name); + } + }; + + React.useEffect(() => { + setAuthTypes(null); + loadAuthTypes() + }, [values.engine]); + + if (!driver) return null; + const disabledFields = (currentAuthType ? currentAuthType.disabledFields : null) || []; + + return ( + <> + {!!authTypes && ( + + {authTypes.map(auth => ( + + ))} + + )} + + + + + + ); +} + export default function ConnectionModal({ modalState, connection = undefined }) { const [sqlConnectResult, setSqlConnectResult] = React.useState(null); const extensions = useExtensions(); @@ -40,7 +83,7 @@ export default function ConnectionModal({ modalState, connection = undefined }) return ( {connection ? 'Edit connection' : 'Add connection'} - + @@ -53,16 +96,7 @@ export default function ConnectionModal({ modalState, connection = undefined }) */} - - - - - - - - - - + {!isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'connected' && (
diff --git a/packages/web/src/themes/ThemeHelmet.js b/packages/web/src/themes/ThemeHelmet.js index 970074066..7e4c5d563 100644 --- a/packages/web/src/themes/ThemeHelmet.js +++ b/packages/web/src/themes/ThemeHelmet.js @@ -39,7 +39,11 @@ export default function ThemeHelmet() { color: ${theme.input_font1}; border: 1px solid ${theme.border}; } - + + input[disabled] { + background-color: ${theme.input_background2}; + } + select { background-color: ${theme.input_background}; color: ${theme.input_font1};