mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
feat(core-connections): CB-937 require credentials if we need to during test connection
This commit is contained in:
@@ -55,11 +55,18 @@ export class ConnectionAuthService {
|
||||
}
|
||||
|
||||
const sshConfig = connection.networkHandlersConfig.find(state => state.id === SSH_TUNNEL_ID);
|
||||
const sshAuthRequired = sshConfig?.enabled && !sshConfig?.savePassword;
|
||||
const networkHandlers: string[] = [];
|
||||
|
||||
const isSSHAuthNeeded = sshConfig?.enabled && !sshConfig?.savePassword;
|
||||
if (sshAuthRequired) {
|
||||
networkHandlers.push(SSH_TUNNEL_ID);
|
||||
}
|
||||
|
||||
if (connection.authNeeded || isSSHAuthNeeded) {
|
||||
await this.commonDialogService.open(DatabaseAuthDialog, connectionId);
|
||||
if (connection.authNeeded || sshAuthRequired) {
|
||||
await this.commonDialogService.open(DatabaseAuthDialog, {
|
||||
connectionId,
|
||||
networkHandlers,
|
||||
});
|
||||
} else {
|
||||
await this.connectionInfoResource.init({ id: connectionId });
|
||||
}
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled, { css } from 'reshadow';
|
||||
|
||||
import { SubmittingForm, useFocus, Button } from '@cloudbeaver/core-blocks';
|
||||
import { CommonDialogWrapper, DialogComponentProps } from '@cloudbeaver/core-dialogs';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { useDBDriver } from '../useDBDriver';
|
||||
import { ConnectionCredentialsForm } from './ConnectionCredentialsForm';
|
||||
|
||||
const styles = css`
|
||||
CommonDialogWrapper {
|
||||
min-height: 400px;
|
||||
min-width: 500px;
|
||||
}
|
||||
SubmittingForm {
|
||||
overflow: auto;
|
||||
margin: auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
ConnectionCredentialsForm {
|
||||
align-content: center;
|
||||
}
|
||||
Button {
|
||||
margin-left: auto;
|
||||
}
|
||||
`;
|
||||
|
||||
interface Payload {
|
||||
config: ConnectionConfig;
|
||||
authModelId: string | null;
|
||||
networkHandlers?: string[];
|
||||
driverId?: string;
|
||||
}
|
||||
|
||||
export const ConnectionCredentialsDialog = observer(function ConnectionCredentialsDialog({
|
||||
payload,
|
||||
rejectDialog,
|
||||
resolveDialog,
|
||||
}: DialogComponentProps<Payload>) {
|
||||
const translate = useTranslate();
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
const { driver } = useDBDriver(payload.driverId || '');
|
||||
|
||||
return styled(useStyles(styles))(
|
||||
<CommonDialogWrapper
|
||||
title={translate('connections_connection_credentials_provisioning')}
|
||||
subTitle={translate('connections_connection_credentials_provisioning_description')}
|
||||
icon={driver?.icon}
|
||||
footer={(
|
||||
<Button mod={['unelevated']} onClick={() => resolveDialog()}>
|
||||
{translate('ui_apply')}
|
||||
</Button>
|
||||
)}
|
||||
onReject={rejectDialog}
|
||||
>
|
||||
<SubmittingForm ref={focusedRef} onSubmit={() => resolveDialog()}>
|
||||
<ConnectionCredentialsForm
|
||||
config={payload.config}
|
||||
authModelId={payload.authModelId}
|
||||
networkHandlers={payload.networkHandlers}
|
||||
formId={payload.config.connectionId || payload.driverId}
|
||||
/>
|
||||
</SubmittingForm>
|
||||
</CommonDialogWrapper>
|
||||
);
|
||||
});
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { BASE_CONTAINERS_STYLES, Container, FieldCheckboxNew, Group, GroupTitle, ObjectPropertyInfoFormNew, TextPlaceholder, useMapResource } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { DatabaseAuthModelsResource } from '../DatabaseAuthModelsResource';
|
||||
import type { IConnectionAuthCredentialsConfig } from './IConnectionAuthCredentialsConfig';
|
||||
import { NetworkHandlers } from './NetworkHandlers';
|
||||
|
||||
interface Props {
|
||||
config: Partial<IConnectionAuthCredentialsConfig>;
|
||||
authModelId: string | null;
|
||||
networkHandlers?: string[];
|
||||
formId?: string;
|
||||
allowSaveCredentials?: boolean;
|
||||
disabled?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const ConnectionCredentialsForm: React.FC<Props> = observer(function ConnectionCredentialsForm({
|
||||
config, networkHandlers, authModelId, formId, allowSaveCredentials, disabled, className,
|
||||
}) {
|
||||
const translate = useTranslate();
|
||||
const { data: authModel } = useMapResource(DatabaseAuthModelsResource, authModelId);
|
||||
|
||||
return styled(useStyles(BASE_CONTAINERS_STYLES))(
|
||||
<Container className={className}>
|
||||
{authModel && (
|
||||
<Group gap small>
|
||||
{authModel.properties ? (
|
||||
<>
|
||||
{!!networkHandlers?.length && <GroupTitle>{translate('connections_database_authentication')}</GroupTitle>}
|
||||
<ObjectPropertyInfoFormNew
|
||||
autofillToken={`section-${formId || ''} section-auth`}
|
||||
properties={authModel.properties}
|
||||
state={config.credentials}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{allowSaveCredentials && (
|
||||
<FieldCheckboxNew
|
||||
id={formId || 'DBAuthSaveCredentials'}
|
||||
name="saveCredentials"
|
||||
label={translate('connections_connection_edit_save_credentials')}
|
||||
disabled={disabled}
|
||||
state={config}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<TextPlaceholder>Authentication data is not avaliable</TextPlaceholder>
|
||||
)}
|
||||
</Group>
|
||||
)}
|
||||
{networkHandlers && config.networkHandlersConfig && (
|
||||
<NetworkHandlers
|
||||
networkHandlers={networkHandlers}
|
||||
networkHandlersConfig={config.networkHandlersConfig}
|
||||
allowSaveCredentials={allowSaveCredentials}
|
||||
disabled={disabled}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
});
|
||||
+4
-4
@@ -8,8 +8,8 @@
|
||||
|
||||
import type { NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import type { ConnectionInitConfig } from '../ConnectionInfoResource';
|
||||
|
||||
export interface IFormInitConfig extends Omit<Required<ConnectionInitConfig>, 'id'> {
|
||||
networkCredentials: NetworkHandlerConfigInput[];
|
||||
export interface IConnectionAuthCredentialsConfig {
|
||||
credentials: any;
|
||||
networkHandlersConfig: NetworkHandlerConfigInput[];
|
||||
saveCredentials: boolean | undefined;
|
||||
}
|
||||
+16
-19
@@ -11,39 +11,36 @@ import styled from 'reshadow';
|
||||
|
||||
import { BASE_CONTAINERS_STYLES, FieldCheckboxNew, GroupTitle, InputFieldNew, useMapResource } from '@cloudbeaver/core-blocks';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import type { NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { NetworkHandlerResource } from '../NetworkHandlerResource';
|
||||
import type { IFormInitConfig } from './IFormInitConfig';
|
||||
|
||||
interface Props {
|
||||
config: IFormInitConfig;
|
||||
sshHandlerId: string;
|
||||
allowPasswordSave: boolean;
|
||||
disabled: boolean;
|
||||
className?: string;
|
||||
id: string;
|
||||
networkHandlersConfig: NetworkHandlerConfigInput[];
|
||||
allowSaveCredentials?: boolean;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export const SSHAuthForm: React.FC<Props> = observer(function SSHAuthForm({
|
||||
config, sshHandlerId, allowPasswordSave, disabled, className,
|
||||
}) {
|
||||
export const NetworkHandlerAuthForm: React.FC<Props> = observer(function NetworkHandlerAuthForm({ id, networkHandlersConfig, allowSaveCredentials, disabled }) {
|
||||
const translate = useTranslate();
|
||||
const handler = useMapResource(NetworkHandlerResource, sshHandlerId);
|
||||
const handler = useMapResource(NetworkHandlerResource, id);
|
||||
|
||||
if (!config.networkCredentials.some(state => state.id === sshHandlerId)) {
|
||||
config.networkCredentials.push({
|
||||
id: sshHandlerId,
|
||||
if (!networkHandlersConfig.some(state => state.id === id)) {
|
||||
networkHandlersConfig!.push({
|
||||
id: id,
|
||||
userName: '',
|
||||
password: '',
|
||||
savePassword: false,
|
||||
});
|
||||
}
|
||||
|
||||
const state = config.networkCredentials.find(state => state.id === sshHandlerId)!;
|
||||
const state = networkHandlersConfig.find(state => state.id === id)!;
|
||||
|
||||
return styled(useStyles(BASE_CONTAINERS_STYLES))(
|
||||
<>
|
||||
<GroupTitle>{translate(handler.data?.label || 'connections_network_handler_ssh_tunnel_title')}</GroupTitle>
|
||||
<GroupTitle>{handler.data?.label || translate(`connections_network_handler_${id}_title`, 'connections_network_handler_default_title')}</GroupTitle>
|
||||
<InputFieldNew
|
||||
type="text"
|
||||
name="userName"
|
||||
@@ -51,7 +48,7 @@ export const SSHAuthForm: React.FC<Props> = observer(function SSHAuthForm({
|
||||
disabled={disabled}
|
||||
mod='surface'
|
||||
>
|
||||
{translate('connections_network_handler_ssh_tunnel_user')}
|
||||
{translate(`connections_network_handler_${id}_user`, 'connections_network_handler_default_user')}
|
||||
</InputFieldNew>
|
||||
<InputFieldNew
|
||||
type="password"
|
||||
@@ -60,11 +57,11 @@ export const SSHAuthForm: React.FC<Props> = observer(function SSHAuthForm({
|
||||
disabled={disabled}
|
||||
mod='surface'
|
||||
>
|
||||
{translate('connections_network_handler_ssh_tunnel_password')}
|
||||
{translate(`connections_network_handler_${id}_password`, 'connections_network_handler_default_password')}
|
||||
</InputFieldNew>
|
||||
{allowPasswordSave && (
|
||||
{allowSaveCredentials && (
|
||||
<FieldCheckboxNew
|
||||
id={sshHandlerId + ' savePassword'}
|
||||
id={id + ' savePassword'}
|
||||
name="savePassword"
|
||||
state={state}
|
||||
label={translate('connections_connection_edit_save_credentials')}
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import styled from 'reshadow';
|
||||
|
||||
import { BASE_CONTAINERS_STYLES, Group } from '@cloudbeaver/core-blocks';
|
||||
import type { NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
import { useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { NetworkHandlerAuthForm } from './NetworkHandlerAuthForm';
|
||||
|
||||
interface Props {
|
||||
networkHandlers: string[];
|
||||
networkHandlersConfig: NetworkHandlerConfigInput[];
|
||||
disabled?: boolean;
|
||||
allowSaveCredentials?: boolean;
|
||||
}
|
||||
|
||||
export const NetworkHandlers: React.FC<Props> = observer(function NetworkHandlers({ networkHandlers, networkHandlersConfig, allowSaveCredentials, disabled }) {
|
||||
const styles = useStyles(BASE_CONTAINERS_STYLES);
|
||||
|
||||
if (!networkHandlers.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return styled(styles)(
|
||||
<Group gap small>
|
||||
{networkHandlers.map(handler => (
|
||||
<NetworkHandlerAuthForm
|
||||
key={handler}
|
||||
id={handler}
|
||||
networkHandlersConfig={networkHandlersConfig}
|
||||
allowSaveCredentials={allowSaveCredentials}
|
||||
disabled={disabled}
|
||||
/>
|
||||
))}
|
||||
</Group>
|
||||
);
|
||||
});
|
||||
+2
-2
@@ -12,9 +12,9 @@ import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import type { MetadataValueGetter } from '@cloudbeaver/core-utils';
|
||||
|
||||
import { ConnectionsResource } from '../../Administration/ConnectionsResource';
|
||||
import { connectionConfigContext } from '../connectionConfigContext';
|
||||
import { ConnectionFormService } from '../ConnectionFormService';
|
||||
import { connectionFormStateContext } from '../connectionFormStateContext';
|
||||
import { connectionConfigContext } from '../Contexts/connectionConfigContext';
|
||||
import { connectionFormStateContext } from '../Contexts/connectionFormStateContext';
|
||||
import type { IConnectionFormProps, IConnectionFormState, IConnectionFormSubmitData } from '../IConnectionFormProps';
|
||||
import { ConnectionAccess } from './ConnectionAccess';
|
||||
import type { IConnectionAccessTabState } from './IConnectionAccessTabState';
|
||||
|
||||
@@ -16,8 +16,8 @@ import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import type { ConnectionConfig } from '@cloudbeaver/core-sdk';
|
||||
import { useStyles, composes } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { connectionConfigContext } from './connectionConfigContext';
|
||||
import { ConnectionFormService } from './ConnectionFormService';
|
||||
import { connectionConfigContext } from './Contexts/connectionConfigContext';
|
||||
import type { IConnectionFormState } from './IConnectionFormProps';
|
||||
|
||||
const tabsStyles = css`
|
||||
|
||||
@@ -8,10 +8,14 @@
|
||||
|
||||
import { PlaceholderContainer, TabsContainer } from '@cloudbeaver/core-blocks';
|
||||
import { injectable } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs';
|
||||
import { ENotificationType, NotificationService } from '@cloudbeaver/core-events';
|
||||
import { ExecutorHandlersCollection, ExecutorInterrupter, IExecutorHandler, IExecutorHandlersCollection } from '@cloudbeaver/core-executor';
|
||||
|
||||
import { ConnectionCredentialsDialog } from '../ConnectionCredentials/ConnectionCredentialsDialog';
|
||||
import { ConnectionFormBaseActions } from './ConnectionFormBaseActions';
|
||||
import { connectionConfigContext } from './Contexts/connectionConfigContext';
|
||||
import { connectionCredentialsStateContext } from './Contexts/connectionCredentialsStateContext';
|
||||
import type { IConnectionFormProps, IConnectionFormState, IConnectionFormFillConfigData, IConnectionFormSubmitData } from './IConnectionFormProps';
|
||||
|
||||
export interface IConnectionFormValidation {
|
||||
@@ -42,7 +46,8 @@ export class ConnectionFormService {
|
||||
readonly formStateTask: IExecutorHandlersCollection<IConnectionFormState>;
|
||||
|
||||
constructor(
|
||||
private readonly notificationService: NotificationService
|
||||
private readonly notificationService: NotificationService,
|
||||
private readonly commonDialogService: CommonDialogService,
|
||||
) {
|
||||
this.tabsContainer = new TabsContainer();
|
||||
this.actionsContainer = new PlaceholderContainer();
|
||||
@@ -60,6 +65,7 @@ export class ConnectionFormService {
|
||||
this.formStateTask
|
||||
.before<IConnectionFormSubmitData>(this.prepareConfigTask, state => ({ state, submitType: 'submit' }));
|
||||
|
||||
this.prepareConfigTask.addPostHandler(this.ensureCredentialsExisting);
|
||||
this.formSubmittingTask.addPostHandler(this.showSubmittingStatusMessage);
|
||||
this.formValidationTask.addPostHandler(this.ensureValidation);
|
||||
|
||||
@@ -115,6 +121,35 @@ export class ConnectionFormService {
|
||||
}
|
||||
};
|
||||
|
||||
private ensureCredentialsExisting: IExecutorHandler<IConnectionFormSubmitData> = async (data, contexts) => {
|
||||
const credentialsState = contexts.getContext(connectionCredentialsStateContext);
|
||||
|
||||
if (data.submitType !== 'test' || (!credentialsState.authModelId && !credentialsState.networkHandlers.length)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const config = contexts.getContext(connectionConfigContext);
|
||||
|
||||
if (config.credentials === undefined && credentialsState.authModelId) {
|
||||
config.credentials = {};
|
||||
}
|
||||
|
||||
if (config.networkHandlersConfig === undefined && credentialsState.networkHandlers.length > 0) {
|
||||
config.networkHandlersConfig = [];
|
||||
}
|
||||
|
||||
const result = await this.commonDialogService.open(ConnectionCredentialsDialog, {
|
||||
config,
|
||||
authModelId: credentialsState.authModelId,
|
||||
networkHandlers: credentialsState.networkHandlers,
|
||||
driverId: config.driverId,
|
||||
});
|
||||
|
||||
if (result === DialogueStateResult.Rejected) {
|
||||
ExecutorInterrupter.interrupt(contexts);
|
||||
}
|
||||
};
|
||||
|
||||
private ensureValidation: IExecutorHandler<IConnectionFormSubmitData> = (data, contexts) => {
|
||||
const validation = contexts.getContext(this.connectionValidationContext);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { DatabaseConnection } from '../Administration/ConnectionsResource';
|
||||
import { EConnectionFeature } from '../EConnectionFeature';
|
||||
import { connectionFormConfigureContext } from './connectionFormConfigureContext';
|
||||
import type { ConnectionFormService } from './ConnectionFormService';
|
||||
import { connectionFormStateContext, IConnectionFormStateInfo } from './connectionFormStateContext';
|
||||
import { connectionFormStateContext, IConnectionFormStateInfo } from './Contexts/connectionFormStateContext';
|
||||
import type { IConnectionFormState, ConnectionFormMode, ConnectionFormType, IConnectionFormSubmitData } from './IConnectionFormProps';
|
||||
|
||||
export class ConnectionFormState implements IConnectionFormState {
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* CloudBeaver - Cloud Database Manager
|
||||
* Copyright (C) 2020-2021 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0.
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
interface IConnectionCredentialsState {
|
||||
authModelId: string | null;
|
||||
networkHandlers: string[];
|
||||
}
|
||||
|
||||
interface IConnectionCredentialsStateContext extends IConnectionCredentialsState {
|
||||
requireAuthModel: (id: string) => void;
|
||||
requireNetworkHandler: (id: string) => void;
|
||||
}
|
||||
|
||||
export function connectionCredentialsStateContext(): IConnectionCredentialsStateContext {
|
||||
return {
|
||||
authModelId: null,
|
||||
networkHandlers: [],
|
||||
requireAuthModel(id) {
|
||||
this.authModelId = id;
|
||||
},
|
||||
requireNetworkHandler(id) {
|
||||
this.networkHandlers.push(id);
|
||||
},
|
||||
};
|
||||
}
|
||||
+2
-2
@@ -11,9 +11,9 @@ import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { isObjectPropertyInfoStateEqual } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import { DBDriverResource } from '../../DBDriverResource';
|
||||
import { connectionConfigContext } from '../connectionConfigContext';
|
||||
import { ConnectionFormService } from '../ConnectionFormService';
|
||||
import { connectionFormStateContext } from '../connectionFormStateContext';
|
||||
import { connectionConfigContext } from '../Contexts/connectionConfigContext';
|
||||
import { connectionFormStateContext } from '../Contexts/connectionFormStateContext';
|
||||
import type { IConnectionFormFillConfigData, IConnectionFormSubmitData, IConnectionFormState } from '../IConnectionFormProps';
|
||||
import { DriverProperties } from './DriverProperties';
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { CachedMapResource, ConnectionConfig, GetConnectionsQueryVariables
|
||||
import type { MetadataMap } from '@cloudbeaver/core-utils';
|
||||
|
||||
import type { DatabaseConnection } from '../Administration/ConnectionsResource';
|
||||
import type { IConnectionFormStateInfo } from './connectionFormStateContext';
|
||||
import type { IConnectionFormStateInfo } from './Contexts/connectionFormStateContext';
|
||||
|
||||
export type ConnectionFormMode = 'edit' | 'create';
|
||||
export type ConnectionFormType = 'admin' | 'public';
|
||||
|
||||
+30
-4
@@ -17,13 +17,16 @@ import { DatabaseAuthModelsResource } from '../../DatabaseAuthModelsResource';
|
||||
import { DBDriverResource } from '../../DBDriverResource';
|
||||
import { getUniqueConnectionName } from '../../getUniqueConnectionName';
|
||||
import { isJDBCConnection } from '../../isJDBCConnection';
|
||||
import { connectionConfigContext } from '../connectionConfigContext';
|
||||
import { connectionFormConfigureContext } from '../connectionFormConfigureContext';
|
||||
import { ConnectionFormService } from '../ConnectionFormService';
|
||||
import { connectionFormStateContext } from '../connectionFormStateContext';
|
||||
import { connectionConfigContext } from '../Contexts/connectionConfigContext';
|
||||
import { connectionCredentialsStateContext } from '../Contexts/connectionCredentialsStateContext';
|
||||
import { connectionFormStateContext } from '../Contexts/connectionFormStateContext';
|
||||
import type { IConnectionFormSubmitData, IConnectionFormFillConfigData, IConnectionFormState } from '../IConnectionFormProps';
|
||||
import { Options } from './Options';
|
||||
|
||||
const USER_NAME_AUTH_PROPERTY_ID = 'userName';
|
||||
|
||||
@injectable()
|
||||
export class ConnectionOptionsTabService extends Bootstrap {
|
||||
constructor(
|
||||
@@ -124,7 +127,7 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
}
|
||||
}
|
||||
|
||||
private validate(
|
||||
private async validate(
|
||||
{
|
||||
state,
|
||||
}: IConnectionFormSubmitData,
|
||||
@@ -135,6 +138,15 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
if (!state.config.name?.length) {
|
||||
validation.error("Field 'name' can't be empty");
|
||||
}
|
||||
|
||||
if (state.config.authModelId && state.config.saveCredentials) {
|
||||
const authProperties = await this.getConnectionAuthModelProperties(state.config.authModelId, state.info);
|
||||
const userNameProperty = authProperties.find(property => property.id === USER_NAME_AUTH_PROPERTY_ID);
|
||||
|
||||
if (userNameProperty && (!state.config.credentials || !state.config.credentials[USER_NAME_AUTH_PROPERTY_ID])) {
|
||||
validation.error(`Field '${userNameProperty.displayName || 'User name'}' can't be empty`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fillConfig(
|
||||
@@ -199,6 +211,7 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
contexts: IExecutionContextProvider<IConnectionFormSubmitData>
|
||||
) {
|
||||
const config = contexts.getContext(connectionConfigContext);
|
||||
const credentialsState = contexts.getContext(connectionCredentialsStateContext);
|
||||
|
||||
const driver = await this.dbDriverResource.load(state.config.driverId!, ['includeProviderProperties']);
|
||||
|
||||
@@ -240,7 +253,15 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
const properties = await this.getConnectionAuthModelProperties(config.authModelId, state.info);
|
||||
|
||||
if (this.isCredentialsChanged(properties, state.config.credentials)) {
|
||||
config.credentials = state.config.credentials;
|
||||
config.credentials = { ...state.config.credentials };
|
||||
}
|
||||
|
||||
if (
|
||||
config.authModelId
|
||||
&& !state.config?.saveCredentials
|
||||
&& (!state.config.credentials || hasMissingCredentials(properties, state.config.credentials))
|
||||
) {
|
||||
credentialsState.requireAuthModel(config.authModelId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,3 +353,8 @@ export class ConnectionOptionsTabService extends Bootstrap {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
function hasMissingCredentials(authProperties: ObjectPropertyInfo[], credentials: Record<string, any>) {
|
||||
return authProperties.some(property => property.id === USER_NAME_AUTH_PROPERTY_ID)
|
||||
&& !credentials[USER_NAME_AUTH_PROPERTY_ID];
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
|
||||
import { isLocalConnection } from '../../Administration/ConnectionsResource';
|
||||
import { connectionFormConfigureContext } from '../connectionFormConfigureContext';
|
||||
import { ConnectionFormService } from '../ConnectionFormService';
|
||||
import { connectionFormStateContext } from '../connectionFormStateContext';
|
||||
import { connectionFormStateContext } from '../Contexts/connectionFormStateContext';
|
||||
import type { IConnectionFormState } from '../IConnectionFormProps';
|
||||
import { ConnectionFormAuthenticationAction } from './ConnectionFormAuthenticationAction';
|
||||
import { OriginInfo } from './OriginInfo';
|
||||
|
||||
@@ -13,10 +13,11 @@ import type { NetworkHandlerConfigInput } from '@cloudbeaver/core-sdk';
|
||||
import type { DatabaseConnection } from '../../Administration/ConnectionsResource';
|
||||
import { DBDriverResource } from '../../DBDriverResource';
|
||||
import { SSH_TUNNEL_ID } from '../../NetworkHandlerResource';
|
||||
import { connectionConfigContext } from '../connectionConfigContext';
|
||||
import { connectionFormConfigureContext } from '../connectionFormConfigureContext';
|
||||
import { ConnectionFormService } from '../ConnectionFormService';
|
||||
import { connectionFormStateContext } from '../connectionFormStateContext';
|
||||
import { connectionConfigContext } from '../Contexts/connectionConfigContext';
|
||||
import { connectionCredentialsStateContext } from '../Contexts/connectionCredentialsStateContext';
|
||||
import { connectionFormStateContext } from '../Contexts/connectionFormStateContext';
|
||||
import type { IConnectionFormFillConfigData, IConnectionFormState, IConnectionFormSubmitData } from '../IConnectionFormProps';
|
||||
import { SSH } from './SSH';
|
||||
import { SSHTab } from './SSHTab';
|
||||
@@ -118,13 +119,16 @@ export class ConnectionSSHTabService extends Bootstrap {
|
||||
}
|
||||
|
||||
for (const handler of config.networkHandlersConfig) {
|
||||
if (handler.enabled && handler.savePassword && this.isChanged(handler, info)) {
|
||||
if (!handler.userName?.length) {
|
||||
validation.error("Field SSH 'User' can't be empty");
|
||||
}
|
||||
if (!handler.password?.length) {
|
||||
validation.error("Field SSH 'Password' can't be empty");
|
||||
if (handler.enabled && this.isChanged(handler, info)) {
|
||||
if (handler.savePassword) {
|
||||
if (!handler.userName?.length) {
|
||||
validation.error("Field SSH 'User' can't be empty");
|
||||
}
|
||||
if (!handler.password?.length) {
|
||||
validation.error("Field SSH 'Password' can't be empty");
|
||||
}
|
||||
}
|
||||
|
||||
if (!handler.properties?.host?.length) {
|
||||
validation.error("Field SSH 'Host' can't be empty");
|
||||
}
|
||||
@@ -144,22 +148,31 @@ export class ConnectionSSHTabService extends Bootstrap {
|
||||
contexts: IExecutionContextProvider<IConnectionFormSubmitData>
|
||||
) {
|
||||
const config = contexts.getContext(connectionConfigContext);
|
||||
const credentialsState = contexts.getContext(connectionCredentialsStateContext);
|
||||
|
||||
if (!state.config.networkHandlersConfig || state.config.networkHandlersConfig.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const configs: NetworkHandlerConfigInput[] = [];
|
||||
let sshHandler: NetworkHandlerConfigInput | undefined;
|
||||
|
||||
for (const handler of state.config.networkHandlersConfig) {
|
||||
if (this.isChanged(handler, state.info)) {
|
||||
configs.push(handler);
|
||||
configs.push({ ...handler });
|
||||
}
|
||||
if (handler.id === SSH_TUNNEL_ID) {
|
||||
sshHandler = handler;
|
||||
}
|
||||
}
|
||||
|
||||
if (configs.length > 0) {
|
||||
config.networkHandlersConfig = configs;
|
||||
}
|
||||
|
||||
if (sshHandler?.enabled && !sshHandler.savePassword && hasMissingCredentials(sshHandler)) {
|
||||
credentialsState.requireNetworkHandler(SSH_TUNNEL_ID);
|
||||
}
|
||||
}
|
||||
|
||||
private formState(
|
||||
@@ -198,3 +211,7 @@ export class ConnectionSSHTabService extends Bootstrap {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function hasMissingCredentials(handler: NetworkHandlerConfigInput): boolean {
|
||||
return !handler.userName;
|
||||
}
|
||||
|
||||
@@ -14,16 +14,16 @@ import { NotificationService } from '@cloudbeaver/core-events';
|
||||
import { ErrorDetailsDialog } from '@cloudbeaver/core-notifications';
|
||||
import { GQLErrorCatcher } from '@cloudbeaver/core-sdk';
|
||||
|
||||
import type { IConnectionAuthCredentialsConfig } from '../ConnectionCredentials/IConnectionAuthCredentialsConfig';
|
||||
import { ConnectionInfoResource, ConnectionInitConfig } from '../ConnectionInfoResource';
|
||||
import { DBDriverResource } from '../DBDriverResource';
|
||||
import type { IFormInitConfig } from './IFormInitConfig';
|
||||
|
||||
@injectable()
|
||||
export class DBAuthDialogController implements IInitializableController, IDestructibleController {
|
||||
isAuthenticating = false;
|
||||
config: IFormInitConfig = {
|
||||
config: IConnectionAuthCredentialsConfig = {
|
||||
credentials: {},
|
||||
networkCredentials: [],
|
||||
networkHandlersConfig: [],
|
||||
saveCredentials: false,
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ export class DBAuthDialogController implements IInitializableController, IDestru
|
||||
});
|
||||
}
|
||||
|
||||
init(connectionId: string, onClose: () => void) {
|
||||
init(connectionId: string, onClose: () => void): void {
|
||||
this.connectionId = connectionId;
|
||||
this.close = onClose;
|
||||
this.loadAuthModel();
|
||||
@@ -56,7 +56,7 @@ export class DBAuthDialogController implements IInitializableController, IDestru
|
||||
this.isDistructed = true;
|
||||
}
|
||||
|
||||
login = async () => {
|
||||
login = async (): Promise<void> => {
|
||||
if (this.isAuthenticating) {
|
||||
return;
|
||||
}
|
||||
@@ -74,7 +74,7 @@ export class DBAuthDialogController implements IInitializableController, IDestru
|
||||
}
|
||||
};
|
||||
|
||||
showDetails = () => {
|
||||
showDetails = (): void => {
|
||||
if (this.error.exception) {
|
||||
this.commonDialogService.open(ErrorDetailsDialog, this.error.exception);
|
||||
}
|
||||
@@ -90,8 +90,8 @@ export class DBAuthDialogController implements IInitializableController, IDestru
|
||||
config.saveCredentials = this.config.saveCredentials;
|
||||
}
|
||||
|
||||
if (this.config.networkCredentials.length > 0) {
|
||||
config.networkCredentials = this.config.networkCredentials;
|
||||
if (this.config.networkHandlersConfig.length > 0) {
|
||||
config.networkCredentials = this.config.networkHandlersConfig;
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
@@ -14,26 +14,18 @@ import {
|
||||
SubmittingForm,
|
||||
Loader,
|
||||
useFocus,
|
||||
BASE_CONTAINERS_STYLES,
|
||||
Container,
|
||||
Group,
|
||||
FieldCheckboxNew,
|
||||
ObjectPropertyInfoFormNew,
|
||||
GroupTitle,
|
||||
ErrorMessage,
|
||||
TextPlaceholder,
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { useController } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogWrapper, DialogComponentProps } from '@cloudbeaver/core-dialogs';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
import { composes, useStyles } from '@cloudbeaver/core-theming';
|
||||
|
||||
import { SSH_TUNNEL_ID } from '../NetworkHandlerResource';
|
||||
import { ConnectionCredentialsForm } from '../ConnectionCredentials/ConnectionCredentialsForm';
|
||||
import { useConnectionInfo } from '../useConnectionInfo';
|
||||
import { useDBDriver } from '../useDBDriver';
|
||||
import { DBAuthDialogController } from './DBAuthDialogController';
|
||||
import { DBAuthDialogFooter } from './DBAuthDialogFooter';
|
||||
import { SSHAuthForm } from './SSHAuthForm';
|
||||
|
||||
const styles = composes(
|
||||
css`
|
||||
@@ -53,7 +45,7 @@ const styles = composes(
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
Container {
|
||||
ConnectionCredentialsForm {
|
||||
align-content: center;
|
||||
}
|
||||
ErrorMessage {
|
||||
@@ -61,31 +53,33 @@ const styles = composes(
|
||||
}
|
||||
`);
|
||||
|
||||
interface Payload {
|
||||
connectionId: string;
|
||||
networkHandlers: string[];
|
||||
}
|
||||
|
||||
export const DatabaseAuthDialog = observer(function DatabaseAuthDialog({
|
||||
payload,
|
||||
options,
|
||||
rejectDialog,
|
||||
}: DialogComponentProps<string>) {
|
||||
const connection = useConnectionInfo(payload);
|
||||
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
const { driver } = useDBDriver(connection.connectionInfo?.driverId || '');
|
||||
const controller = useController(DBAuthDialogController, payload, rejectDialog);
|
||||
}: DialogComponentProps<Payload>) {
|
||||
const translate = useTranslate();
|
||||
const connection = useConnectionInfo(payload.connectionId);
|
||||
const controller = useController(DBAuthDialogController, payload.connectionId, rejectDialog);
|
||||
|
||||
const { driver } = useDBDriver(connection.connectionInfo?.driverId || '');
|
||||
const { credentialsSavingEnabled } = useAdministrationSettings();
|
||||
const [focusedRef] = useFocus<HTMLFormElement>({ focusFirstChild: true });
|
||||
|
||||
const sshConfig = connection.connectionInfo?.networkHandlersConfig.find(
|
||||
handler => handler.id === SSH_TUNNEL_ID
|
||||
);
|
||||
let authModelId: string | null = null;
|
||||
|
||||
const isAuthNeeded = connection.connectionInfo?.authNeeded;
|
||||
const isSSHAuthNeeded = sshConfig?.enabled && !sshConfig.savePassword;
|
||||
if (connection.connectionInfo?.authNeeded) {
|
||||
authModelId = connection.connectionInfo?.authModel || driver?.defaultAuthModel || null;
|
||||
}
|
||||
|
||||
const title = translate('connections_database_authentication');
|
||||
|
||||
return styled(useStyles(styles, BASE_CONTAINERS_STYLES))(
|
||||
return styled(useStyles(styles))(
|
||||
<CommonDialogWrapper
|
||||
title={title}
|
||||
title={translate('connections_database_authentication')}
|
||||
subTitle={connection.connectionInfo?.name}
|
||||
icon={driver?.icon}
|
||||
footer={(
|
||||
@@ -108,48 +102,14 @@ export const DatabaseAuthDialog = observer(function DatabaseAuthDialog({
|
||||
? <Loader />
|
||||
: (
|
||||
<SubmittingForm ref={focusedRef} onSubmit={controller.login}>
|
||||
<Container>
|
||||
{isAuthNeeded && (
|
||||
<Group gap small>
|
||||
{connection.connectionInfo?.authProperties ? (
|
||||
<>
|
||||
{isSSHAuthNeeded && sshConfig && <GroupTitle>{title}</GroupTitle>}
|
||||
<ObjectPropertyInfoFormNew
|
||||
autofillToken={`section-${connection.connectionInfo?.id || ''} section-auth`}
|
||||
properties={connection.connectionInfo.authProperties}
|
||||
state={controller.config.credentials}
|
||||
disabled={controller.isAuthenticating}
|
||||
/>
|
||||
{credentialsSavingEnabled && (
|
||||
<FieldCheckboxNew
|
||||
id={connection.connectionInfo?.id || 'DBAuthSaveCredentials'}
|
||||
name="saveCredentials"
|
||||
label={translate('connections_connection_edit_save_credentials')}
|
||||
disabled={controller.isAuthenticating}
|
||||
state={controller.config}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<TextPlaceholder>Authentication data is not avaliable</TextPlaceholder>
|
||||
)}
|
||||
</Group>
|
||||
)}
|
||||
{isSSHAuthNeeded && (
|
||||
<Group gap small>
|
||||
{sshConfig ? (
|
||||
<SSHAuthForm
|
||||
config={controller.config}
|
||||
sshHandlerId={sshConfig.id}
|
||||
allowPasswordSave={credentialsSavingEnabled}
|
||||
disabled={controller.isAuthenticating}
|
||||
/>
|
||||
) : (
|
||||
<TextPlaceholder>SSH Authentication data is not avaliable</TextPlaceholder>
|
||||
)}
|
||||
</Group>
|
||||
)}
|
||||
</Container>
|
||||
<ConnectionCredentialsForm
|
||||
config={controller.config}
|
||||
authModelId={authModelId}
|
||||
networkHandlers={payload.networkHandlers}
|
||||
formId={payload.connectionId}
|
||||
allowSaveCredentials={credentialsSavingEnabled}
|
||||
disabled={controller.isAuthenticating}
|
||||
/>
|
||||
</SubmittingForm>
|
||||
)}
|
||||
</CommonDialogWrapper>
|
||||
|
||||
@@ -16,15 +16,17 @@ export * from './ConnectionForm/DriverProperties/ConnectionDriverPropertiesTabSe
|
||||
export * from './ConnectionForm/SSH/ConnectionSSHTabService';
|
||||
export * from './ConnectionForm/OriginInfo/ConnectionOriginInfoTabService';
|
||||
export * from './ConnectionForm/ConnectionAccess/ConnectionAccessTabService';
|
||||
export * from './ConnectionForm/connectionConfigContext';
|
||||
export * from './ConnectionForm/Contexts/connectionConfigContext';
|
||||
export * from './ConnectionForm/ConnectionFormBaseActions';
|
||||
export * from './ConnectionForm/connectionFormConfigureContext';
|
||||
export * from './ConnectionForm/ConnectionForm';
|
||||
export * from './ConnectionForm/ConnectionFormService';
|
||||
export * from './ConnectionForm/ConnectionFormState';
|
||||
export * from './ConnectionForm/connectionFormStateContext';
|
||||
export * from './ConnectionForm/Contexts/connectionFormStateContext';
|
||||
export * from './ConnectionForm/IConnectionFormProps';
|
||||
export * from './ConnectionForm/useConnectionFormState';
|
||||
export * from './ConnectionCredentials/IConnectionAuthCredentialsConfig';
|
||||
export * from './ConnectionCredentials/ConnectionCredentialsForm';
|
||||
|
||||
export * from './extensions/IConnectionProvider';
|
||||
export * from './extensions/IConnectionSetter';
|
||||
@@ -35,8 +37,6 @@ export * from './EConnectionFeature';
|
||||
export * from './ContainerResource';
|
||||
export * from './ConnectionsLocaleService';
|
||||
export * from './DatabaseAuthModelsResource';
|
||||
export * from './DatabaseAuthDialog/IFormInitConfig';
|
||||
export * from './DatabaseAuthDialog/SSHAuthForm';
|
||||
export * from './DBDriverResource';
|
||||
export * from './NetworkHandlerResource';
|
||||
export * from './useConnectionInfo';
|
||||
|
||||
@@ -22,6 +22,8 @@ export default [
|
||||
['connections_connection_create_custom', 'Custom'],
|
||||
['connections_connection_create_search_database', 'Search'],
|
||||
['connections_connection_edit_save_credentials', 'Save credentials'],
|
||||
['connections_connection_credentials_provisioning', 'Credentials provisioning'],
|
||||
['connections_connection_credentials_provisioning_description', 'You need to provide additional credentials to test this connection'],
|
||||
['connections_connection_edit_authentication', 'Authentication'],
|
||||
['connections_connection_edit_settings', 'Settings'],
|
||||
['connections_connection_edit_access', 'Access'],
|
||||
@@ -55,6 +57,9 @@ export default [
|
||||
['connections_network_handler_test', 'Test Tunnel'],
|
||||
['connections_network_handler_test_fail', 'Tunnel test failed'],
|
||||
['connections_network_handler_test_success', 'Tunnel test success'],
|
||||
['connections_network_handler_default_title', 'Network handler'],
|
||||
['connections_network_handler_default_user', 'User'],
|
||||
['connections_network_handler_default_password', 'Password'],
|
||||
['connections_network_handler_ssh_tunnel_title', 'SSH Tunnel'],
|
||||
['connections_network_handler_ssh_tunnel_enable', 'Use SSH Tunnel'],
|
||||
['connections_network_handler_ssh_tunnel_host', 'Host'],
|
||||
|
||||
@@ -19,6 +19,8 @@ export default [
|
||||
['connections_connection_create_custom', 'Настроить'],
|
||||
['connections_connection_create_search_database', 'Найти'],
|
||||
['connections_connection_edit_save_credentials', ' Запомнить данные'],
|
||||
['connections_connection_credentials_provisioning', 'Предоставление данных доступа'],
|
||||
['connections_connection_credentials_provisioning_description', 'Чтобы проверить подключение, необходимо предоставить дополнительные данные доступа'],
|
||||
['connections_connection_edit_authentication', 'Авторизация'],
|
||||
['connections_connection_edit_settings', 'Настройки'],
|
||||
['connections_connection_edit_access', 'Доступ'],
|
||||
@@ -52,6 +54,9 @@ export default [
|
||||
['connections_network_handler_test', 'Проверить подключение'],
|
||||
['connections_network_handler_test_fail', 'Не удалось установить соединение'],
|
||||
['connections_network_handler_test_success', 'Соединение установлено'],
|
||||
['connections_network_handler_default_title', 'Сетевой обработчик'],
|
||||
['connections_network_handler_default_user', 'Пользователь'],
|
||||
['connections_network_handler_default_password', 'Пароль'],
|
||||
['connections_network_handler_ssh_tunnel_title', 'SSH Тунель'],
|
||||
['connections_network_handler_ssh_tunnel_enable', 'Использовать SSH Тунель'],
|
||||
['connections_network_handler_ssh_tunnel_host', 'Хост'],
|
||||
|
||||
@@ -13,6 +13,7 @@ export const defaultENLocale = [
|
||||
['ui_processing_ok', 'Ok'],
|
||||
['ui_processing_create', 'Create'],
|
||||
['ui_processing_save', 'Save'],
|
||||
['ui_apply', 'Apply'],
|
||||
['ui_error_message', 'Error:'],
|
||||
['ui_error_close', 'Close'],
|
||||
['ui_close', 'Close'],
|
||||
|
||||
@@ -11,6 +11,7 @@ export const defaultRULocale = [
|
||||
['ui_processing_ok', 'Принять'],
|
||||
['ui_processing_create', 'Создать'],
|
||||
['ui_processing_save', 'Сохранить'],
|
||||
['ui_apply', 'Применить'],
|
||||
['ui_error_message', 'Ошибка:'],
|
||||
['ui_error_close', 'Закрыть'],
|
||||
['ui_close', 'Закрыть'],
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
*/
|
||||
|
||||
type Cookies = Record<string, string>;
|
||||
type Cookies = Partial<Record<string, string>>;
|
||||
|
||||
export function getCookies(): Cookies {
|
||||
if (!document.cookie) {
|
||||
|
||||
+11
-11
@@ -9,7 +9,7 @@
|
||||
import { observable, makeObservable } from 'mobx';
|
||||
|
||||
import { DBDriverResource, Connection, DatabaseAuthModelsResource, ConnectionInfoResource, DBDriver, ConnectionInitConfig, getUniqueConnectionName } from '@cloudbeaver/core-connections';
|
||||
import type { IFormInitConfig } from '@cloudbeaver/core-connections';
|
||||
import type { IConnectionAuthCredentialsConfig } from '@cloudbeaver/core-connections';
|
||||
import { injectable, IInitializableController, IDestructibleController } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogService } from '@cloudbeaver/core-dialogs';
|
||||
import { NotificationService } from '@cloudbeaver/core-events';
|
||||
@@ -25,7 +25,7 @@ export enum ConnectionStep {
|
||||
|
||||
export interface IConnectionController {
|
||||
template: Connection | null;
|
||||
config: IFormInitConfig;
|
||||
config: IConnectionAuthCredentialsConfig;
|
||||
isConnecting: boolean;
|
||||
onConnect: () => void;
|
||||
}
|
||||
@@ -38,9 +38,9 @@ implements IInitializableController, IDestructibleController, IConnectionControl
|
||||
isConnecting = false;
|
||||
template: Connection | null = null;
|
||||
authModel?: DatabaseAuthModel;
|
||||
config: IFormInitConfig = {
|
||||
config: IConnectionAuthCredentialsConfig = {
|
||||
credentials: {},
|
||||
networkCredentials: [],
|
||||
networkHandlersConfig: [],
|
||||
saveCredentials: false,
|
||||
};
|
||||
|
||||
@@ -95,7 +95,7 @@ implements IInitializableController, IDestructibleController, IConnectionControl
|
||||
this.isDistructed = true;
|
||||
}
|
||||
|
||||
onStep = (step: ConnectionStep) => {
|
||||
onStep = (step: ConnectionStep): void => {
|
||||
this.step = step;
|
||||
this.clearError();
|
||||
|
||||
@@ -104,7 +104,7 @@ implements IInitializableController, IDestructibleController, IConnectionControl
|
||||
}
|
||||
};
|
||||
|
||||
onConnect = async () => {
|
||||
onConnect = async (): Promise<void> => {
|
||||
if (!this.template) {
|
||||
return;
|
||||
}
|
||||
@@ -132,14 +132,14 @@ implements IInitializableController, IDestructibleController, IConnectionControl
|
||||
}
|
||||
};
|
||||
|
||||
onTemplateSelect = async (templateId: string) => {
|
||||
onTemplateSelect = async (templateId: string): Promise<void> => {
|
||||
this.template = this.templateConnections.find(template => template.id === templateId)!;
|
||||
|
||||
await this.loadAuthModel();
|
||||
this.clearError();
|
||||
this.config = {
|
||||
credentials: {},
|
||||
networkCredentials: [],
|
||||
networkHandlersConfig: [],
|
||||
saveCredentials: false,
|
||||
};
|
||||
|
||||
@@ -149,7 +149,7 @@ implements IInitializableController, IDestructibleController, IConnectionControl
|
||||
}
|
||||
};
|
||||
|
||||
onShowDetails = () => {
|
||||
onShowDetails = (): void => {
|
||||
if (this.exception) {
|
||||
this.commonDialogService.open(ErrorDetailsDialog, this.exception);
|
||||
}
|
||||
@@ -165,8 +165,8 @@ implements IInitializableController, IDestructibleController, IConnectionControl
|
||||
config.saveCredentials = this.config.saveCredentials;
|
||||
}
|
||||
|
||||
if (this.config.networkCredentials.length > 0) {
|
||||
config.networkCredentials = this.config.networkCredentials;
|
||||
if (this.config.networkHandlersConfig.length > 0) {
|
||||
config.networkCredentials = this.config.networkHandlersConfig;
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
+16
-37
@@ -15,14 +15,8 @@ import {
|
||||
SubmittingForm,
|
||||
Loader,
|
||||
useFocus,
|
||||
Container,
|
||||
Group,
|
||||
FieldCheckboxNew,
|
||||
BASE_CONTAINERS_STYLES,
|
||||
ObjectPropertyInfoFormNew,
|
||||
GroupTitle
|
||||
} from '@cloudbeaver/core-blocks';
|
||||
import { SSH_TUNNEL_ID, SSHAuthForm } from '@cloudbeaver/core-connections';
|
||||
import { SSH_TUNNEL_ID, ConnectionCredentialsForm } from '@cloudbeaver/core-connections';
|
||||
import { useController } from '@cloudbeaver/core-di';
|
||||
import { CommonDialogWrapper, DialogComponentProps } from '@cloudbeaver/core-dialogs';
|
||||
import { useTranslate } from '@cloudbeaver/core-localization';
|
||||
@@ -73,10 +67,15 @@ export const ConnectionDialog = observer(function ConnectionDialog({
|
||||
const sshConfig = controller.template?.networkHandlersConfig.find(
|
||||
handler => handler.id === SSH_TUNNEL_ID
|
||||
);
|
||||
const sshAuthRequired = sshConfig?.enabled && !sshConfig.savePassword;
|
||||
|
||||
const isSSHAuthNeeded = sshConfig?.enabled && !sshConfig.savePassword;
|
||||
const networkHandlers: string[] = [];
|
||||
|
||||
return styled(useStyles(styles, BASE_CONTAINERS_STYLES))(
|
||||
if (sshAuthRequired) {
|
||||
networkHandlers.push(SSH_TUNNEL_ID);
|
||||
}
|
||||
|
||||
return styled(useStyles(styles))(
|
||||
<CommonDialogWrapper
|
||||
title={translate('basicConnection_connectionDialog_newConnection')}
|
||||
subTitle={subtitle}
|
||||
@@ -104,34 +103,14 @@ export const ConnectionDialog = observer(function ConnectionDialog({
|
||||
</center>
|
||||
) : (
|
||||
<SubmittingForm ref={focusedRef} onSubmit={controller.onConnect}>
|
||||
<Container>
|
||||
<Group gap small>
|
||||
{isSSHAuthNeeded && <GroupTitle>{translate('connections_database_authentication')}</GroupTitle>}
|
||||
<ObjectPropertyInfoFormNew
|
||||
autofillToken={`section-${controller.template?.id || ''} section-auth`}
|
||||
properties={controller.authModel.properties}
|
||||
state={controller.config.credentials}
|
||||
disabled={controller.isConnecting}
|
||||
/>
|
||||
{credentialsSavingEnabled && (
|
||||
<FieldCheckboxNew
|
||||
id={controller.template?.id || 'DBAuthSaveCredentials'}
|
||||
name="saveCredentials"
|
||||
label={translate('connections_connection_edit_save_credentials')}
|
||||
disabled={controller.isConnecting}
|
||||
state={controller.config}
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
{isSSHAuthNeeded && sshConfig && (
|
||||
<SSHAuthForm
|
||||
sshHandlerId={sshConfig.id}
|
||||
config={controller.config}
|
||||
disabled={controller.isConnecting}
|
||||
allowPasswordSave={credentialsSavingEnabled}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
<ConnectionCredentialsForm
|
||||
config={controller.config}
|
||||
authModelId={controller.authModel.id}
|
||||
networkHandlers={networkHandlers}
|
||||
formId={controller.template?.id}
|
||||
allowSaveCredentials={credentialsSavingEnabled}
|
||||
disabled={controller.isConnecting}
|
||||
/>
|
||||
</SubmittingForm>
|
||||
))}
|
||||
{controller.responseMessage && (
|
||||
|
||||
Reference in New Issue
Block a user