mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-23 03:26:00 +00:00
SYNC: private cloud UX + fixes
This commit is contained in:
committed by
Diflow
parent
f2af38da4c
commit
d668128a34
@@ -4,6 +4,7 @@ const { getSshTunnelProxy } = require('./sshTunnelProxy');
|
|||||||
const platformInfo = require('../utility/platformInfo');
|
const platformInfo = require('../utility/platformInfo');
|
||||||
const connections = require('../controllers/connections');
|
const connections = require('../controllers/connections');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
|
const { getCloudFolderEncryptor } = require('./cloudIntf');
|
||||||
|
|
||||||
async function loadConnection(driver, storedConnection, connectionMode) {
|
async function loadConnection(driver, storedConnection, connectionMode) {
|
||||||
const { allowShellConnection, allowConnectionFromEnvVariables } = platformInfo;
|
const { allowShellConnection, allowConnectionFromEnvVariables } = platformInfo;
|
||||||
@@ -88,13 +89,31 @@ async function extractConnectionSslParams(connection) {
|
|||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function decryptCloudConnection(connection) {
|
||||||
|
const m = connection?._id?.match(/^cloud\:\/\/(.+)\/(.+)$/);
|
||||||
|
if (!m) {
|
||||||
|
throw new Error('Invalid cloud connection ID format');
|
||||||
|
}
|
||||||
|
|
||||||
|
const folid = m[1];
|
||||||
|
const cntid = m[2];
|
||||||
|
|
||||||
|
const folderEncryptor = await getCloudFolderEncryptor(folid);
|
||||||
|
return decryptConnection(connection, folderEncryptor);
|
||||||
|
}
|
||||||
|
|
||||||
async function connectUtility(driver, storedConnection, connectionMode, additionalOptions = null) {
|
async function connectUtility(driver, storedConnection, connectionMode, additionalOptions = null) {
|
||||||
const connectionLoaded = await loadConnection(driver, storedConnection, connectionMode);
|
const connectionLoaded = await loadConnection(driver, storedConnection, connectionMode);
|
||||||
|
|
||||||
const connection = {
|
const connection = connectionLoaded?._id?.startsWith('cloud://')
|
||||||
database: connectionLoaded.defaultDatabase,
|
? {
|
||||||
...decryptConnection(connectionLoaded),
|
database: connectionLoaded.defaultDatabase,
|
||||||
};
|
...(await decryptCloudConnection(connectionLoaded)),
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
database: connectionLoaded.defaultDatabase,
|
||||||
|
...decryptConnection(connectionLoaded),
|
||||||
|
};
|
||||||
|
|
||||||
if (!connection.port && driver.defaultPort) {
|
if (!connection.port && driver.defaultPort) {
|
||||||
connection.port = driver.defaultPort.toString();
|
connection.port = driver.defaultPort.toString();
|
||||||
|
|||||||
@@ -91,11 +91,11 @@ function encryptObjectPasswordField(obj, field, encryptor = null) {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptObjectPasswordField(obj, field) {
|
function decryptObjectPasswordField(obj, field, encryptor = null) {
|
||||||
if (obj && obj[field] && obj[field].startsWith('crypt:')) {
|
if (obj && obj[field] && obj[field].startsWith('crypt:')) {
|
||||||
return {
|
return {
|
||||||
...obj,
|
...obj,
|
||||||
[field]: getInternalEncryptor().decrypt(obj[field].substring('crypt:'.length)),
|
[field]: (encryptor || getInternalEncryptor()).decrypt(obj[field].substring('crypt:'.length)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
@@ -115,10 +115,10 @@ function maskConnection(connection) {
|
|||||||
return _.omit(connection, ['password', 'sshPassword', 'sshKeyfilePassword']);
|
return _.omit(connection, ['password', 'sshPassword', 'sshKeyfilePassword']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function decryptConnection(connection) {
|
function decryptConnection(connection, encryptor = null) {
|
||||||
connection = decryptObjectPasswordField(connection, 'password');
|
connection = decryptObjectPasswordField(connection, 'password', encryptor);
|
||||||
connection = decryptObjectPasswordField(connection, 'sshPassword');
|
connection = decryptObjectPasswordField(connection, 'sshPassword', encryptor);
|
||||||
connection = decryptObjectPasswordField(connection, 'sshKeyfilePassword');
|
connection = decryptObjectPasswordField(connection, 'sshKeyfilePassword', encryptor);
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { batchDispatchCacheTriggers, dispatchCacheChange } from './cache';
|
|||||||
import { isAdminPage, isOneOfPage } from './pageDefs';
|
import { isAdminPage, isOneOfPage } from './pageDefs';
|
||||||
import { openWebLink } from './simpleTools';
|
import { openWebLink } from './simpleTools';
|
||||||
import { serializeJsTypesReplacer } from 'dbgate-tools';
|
import { serializeJsTypesReplacer } from 'dbgate-tools';
|
||||||
import { cloudSigninTokenHolder } from '../stores';
|
import { cloudSigninTokenHolder, selectedWidget } from '../stores';
|
||||||
import LicenseLimitMessageModal from '../modals/LicenseLimitMessageModal.svelte';
|
import LicenseLimitMessageModal from '../modals/LicenseLimitMessageModal.svelte';
|
||||||
|
|
||||||
export const strmid = uuidv1();
|
export const strmid = uuidv1();
|
||||||
@@ -290,8 +290,9 @@ export function installNewVolatileConnectionListener() {
|
|||||||
|
|
||||||
export function installNewCloudTokenListener() {
|
export function installNewCloudTokenListener() {
|
||||||
apiOn('got-cloud-token', async tokenHolder => {
|
apiOn('got-cloud-token', async tokenHolder => {
|
||||||
console.log('HOLDER', tokenHolder);
|
// console.log('HOLDER', tokenHolder);
|
||||||
cloudSigninTokenHolder.set(tokenHolder);
|
cloudSigninTokenHolder.set(tokenHolder);
|
||||||
|
selectedWidget.set('cloud-private');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,9 @@
|
|||||||
import { showSnackbarInfo } from '../utility/snackbar';
|
import { showSnackbarInfo } from '../utility/snackbar';
|
||||||
import { isProApp } from '../utility/proTools';
|
import { isProApp } from '../utility/proTools';
|
||||||
import { useCloudContentColorFactory, useConnectionColorFactory } from '../utility/useConnectionColor';
|
import { useCloudContentColorFactory, useConnectionColorFactory } from '../utility/useConnectionColor';
|
||||||
|
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||||
|
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||||
|
import runCommand from '../commands/runCommand';
|
||||||
|
|
||||||
let filter = '';
|
let filter = '';
|
||||||
let domSqlObjectList = null;
|
let domSqlObjectList = null;
|
||||||
@@ -250,8 +253,32 @@
|
|||||||
}}
|
}}
|
||||||
groupContextMenu={createGroupContextMenu}
|
groupContextMenu={createGroupContextMenu}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{#if !cloudContentFlat?.length}
|
||||||
|
<ErrorInfo message="You have no content on DbGate cloud" icon="img info" />
|
||||||
|
<div class="error-info">
|
||||||
|
<div class="m-1"></div>
|
||||||
|
<FormStyledButton
|
||||||
|
value="Create connection on DbGate Cloud"
|
||||||
|
skipWidth
|
||||||
|
on:click={() => {
|
||||||
|
runCommand('new.connectionOnCloud');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</WidgetsInnerContainer>
|
</WidgetsInnerContainer>
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
|
|
||||||
<DatabaseWidgetDetailContent bind:domSqlObjectList showCloudConnection={true} />
|
<DatabaseWidgetDetailContent bind:domSqlObjectList showCloudConnection={true} />
|
||||||
</WidgetColumnBar>
|
</WidgetColumnBar>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.error-info {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user