custom DB URI support (used by Mongo)

This commit is contained in:
Jan Prochazka 2021-04-10 10:47:36 +02:00
parent e8b43820b9
commit 88b4c9daff
6 changed files with 124 additions and 57 deletions

View File

@ -38,6 +38,10 @@ async function connectUtility(driver, storedConnection) {
connection.ssl.key = await fs.readFile(connection.sslKeyFile);
}
if (connection.sslCertFilePassword) {
connection.ssl.password = connection.sslCertFilePassword;
}
if (!connection.ssl.key && !connection.ssl.ca && !connection.ssl.cert) {
// TODO: provide this as an option in settings
// or per-connection as 'reject self-signed certs'

View File

@ -37,6 +37,8 @@ export interface EngineDriver {
engine: string;
title: string;
defaultPort?: number;
supportsDatabaseUrl?: boolean;
databaseUrlPlaceholder?: string;
connect({ server, port, user, password, database }): any;
query(pool: any, sql: string): Promise<QueryResult>;
stream(pool: any, sql: string, options: StreamOptions);

View File

@ -0,0 +1,22 @@
<script lang="ts">
import { getFormContext } from './FormProviderCore.svelte';
import uuidv1 from 'uuid/v1';
export let options = [];
export let name;
const { values, setFieldValue } = getFormContext();
let group = $values[name] ?? options.find(x => x.default)?.value;
$: setFieldValue(name, group);
$: optionsWithId = options.map(x => ({ ...x, id: uuidv1() }));
</script>
{#each optionsWithId as option}
<div>
<input type="radio" bind:group value={option.value} id={option.id} />
<label for={option.id}>{option.label}</label>
</div>
{/each}

View File

@ -86,7 +86,7 @@
</div>
{/if}
{#if !isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'error'}
<div>
<div class="error-result">
Connect failed: <FontIcon icon="img error" />
{sqlConnectResult.error}
</div>
@ -113,4 +113,8 @@
overflow: hidden;
text-overflow: ellipsis;
}
.error-result {
white-space: normal;
}
</style>

View File

@ -2,6 +2,7 @@
import FormPasswordField from '../forms/FormPasswordField.svelte';
import { getFormContext } from '../forms/FormProviderCore.svelte';
import FormRadioGroupField from '../forms/FormRadioGroupField.svelte';
import FormSelectField from '../forms/FormSelectField.svelte';
import FormTextField from '../forms/FormTextField.svelte';
@ -11,6 +12,7 @@
const { values } = getFormContext();
$: authType = $values.authType;
$: engine = $values.engine;
$: useDatabaseUrl = $values.useDatabaseUrl;
$: authTypes = useAuthTypes({ engine });
$: currentAuthType = $authTypes && $authTypes.find(x => x.name == authType);
$: disabledFields = (currentAuthType ? currentAuthType.disabledFields : null) || [];
@ -29,65 +31,85 @@
]}
/>
{#if $authTypes}
<FormSelectField
label="Authentication"
name="authType"
options={$authTypes.map(auth => ({
value: auth.name,
label: auth.title,
}))}
/>
{#if driver?.supportsDatabaseUrl}
<div class="radio">
<FormRadioGroupField
name="useDatabaseUrl"
options={[
{ label: 'Fill database connection details', value: '', default: true },
{ label: 'Use database URL', value: '1' },
]}
/>
</div>
{/if}
<div class="row">
<div class="col-9 mr-1">
<FormTextField
label="Server"
name="server"
disabled={disabledFields.includes('server')}
templateProps={{ noMargin: true }}
/>
</div>
<div class="col-3 mr-1">
<FormTextField
label="Port"
name="port"
disabled={disabledFields.includes('port')}
templateProps={{ noMargin: true }}
placeholder={driver && driver.defaultPort}
/>
</div>
</div>
<div class="row">
<div class="col-6 mr-1">
<FormTextField
label="User"
name="user"
disabled={disabledFields.includes('user')}
templateProps={{ noMargin: true }}
/>
</div>
<div class="col-6 mr-1">
<FormPasswordField
label="Password"
name="password"
disabled={disabledFields.includes('password')}
templateProps={{ noMargin: true }}
/>
</div>
</div>
{#if !disabledFields.includes('password')}
<FormSelectField
label="Password mode"
name="passwordMode"
options={[
{ value: 'saveEncrypted', label: 'Save and encrypt' },
{ value: 'saveRaw', label: 'Save raw (UNSAFE!!)' },
]}
{#if driver?.supportsDatabaseUrl && useDatabaseUrl}
<FormTextField
label="Database URL"
name="databaseUrl"
placeholder={driver?.databaseUrlPlaceholder}
/>
{:else}
{#if $authTypes}
<FormSelectField
label="Authentication"
name="authType"
options={$authTypes.map(auth => ({
value: auth.name,
label: auth.title,
}))}
/>
{/if}
<div class="row">
<div class="col-9 mr-1">
<FormTextField
label="Server"
name="server"
disabled={disabledFields.includes('server')}
templateProps={{ noMargin: true }}
/>
</div>
<div class="col-3 mr-1">
<FormTextField
label="Port"
name="port"
disabled={disabledFields.includes('port')}
templateProps={{ noMargin: true }}
placeholder={driver && driver.defaultPort}
/>
</div>
</div>
<div class="row">
<div class="col-6 mr-1">
<FormTextField
label="User"
name="user"
disabled={disabledFields.includes('user')}
templateProps={{ noMargin: true }}
/>
</div>
<div class="col-6 mr-1">
<FormPasswordField
label="Password"
name="password"
disabled={disabledFields.includes('password')}
templateProps={{ noMargin: true }}
/>
</div>
</div>
{#if !disabledFields.includes('password')}
<FormSelectField
label="Password mode"
name="passwordMode"
options={[
{ value: 'saveEncrypted', label: 'Save and encrypt' },
{ value: 'saveRaw', label: 'Save raw (UNSAFE!!)' },
]}
/>
{/if}
{/if}
<FormTextField label="Display name" name="displayName" />
@ -97,4 +119,11 @@
margin: var(--dim-large-form-margin);
display: flex;
}
.radio {
margin-left: var(--dim-large-form-margin);
display: flex;
}
.radio :global(label) {
margin-right: 10px;
}
</style>

View File

@ -5,6 +5,7 @@
import FormCheckboxField from '../forms/FormCheckboxField.svelte';
import getElectron from '../utility/getElectron';
import FormPasswordField from '../forms/FormPasswordField.svelte';
const { values, setFieldValue } = getFormContext();
const electron = getElectron();
@ -15,5 +16,10 @@
<FormCheckboxField label="Use SSL" name="useSsl" />
<FormElectronFileSelector label="CA Cert (optional)" name="sslCaFile" disabled={!useSsl || !electron} />
<FormElectronFileSelector label="Certificate (optional)" name="sslCertFile" disabled={!useSsl || !electron} />
<FormPasswordField
label="Certificate key file password (optional)"
name="sslCertFilePassword"
disabled={!useSsl || !electron}
/>
<FormElectronFileSelector label="Key file (optional)" name="sslKeyFile" disabled={!useSsl || !electron} />
<FormCheckboxField label="Reject unauthorized" name="sslRejectUnauthorized" disabled={!useSsl} />