diff --git a/e2e-tests/cypress/e2e/browse-data.cy.js b/e2e-tests/cypress/e2e/browse-data.cy.js index 7eb4fdd5e..e45eda9ff 100644 --- a/e2e-tests/cypress/e2e/browse-data.cy.js +++ b/e2e-tests/cypress/e2e/browse-data.cy.js @@ -514,8 +514,8 @@ describe('Data browser data', () => { cy.themeshot('query-result-chart'); }); - // it.only('Private cloud', () => { - // cy.testid('WidgetIconPanel_cloudAccount').click(); - // cy.contains('Sign in with Google').click(); - // }); + it.only('Private cloud', () => { + cy.testid('WidgetIconPanel_cloudAccount').click(); + cy.contains('Sign in with Google').click(); + }); }); diff --git a/e2e-tests/env/browse-data/.env b/e2e-tests/env/browse-data/.env index 63329f03d..94ae674db 100644 --- a/e2e-tests/env/browse-data/.env +++ b/e2e-tests/env/browse-data/.env @@ -1,5 +1,6 @@ CONNECTIONS=mysql,postgres,mongo,redis ALLOW_DBGATE_PRIVATE_CLOUD=1 +REDIRECT_TO_DBGATE_CLOUD_LOGIN=1 LABEL_mysql=MySql-connection SERVER_mysql=localhost diff --git a/packages/api/.env b/packages/api/.env index c979d16f1..d07e42182 100644 --- a/packages/api/.env +++ b/packages/api/.env @@ -2,9 +2,10 @@ DEVMODE=1 SHELL_SCRIPTING=1 ALLOW_DBGATE_PRIVATE_CLOUD=1 DEVWEB=1 +# REDIRECT_TO_DBGATE_CLOUD_LOGIN=1 # PROD_DBGATE_CLOUD=1 # PROD_DBGATE_IDENTITY=1 -LOCAL_DBGATE_CLOUD=1 +# LOCAL_DBGATE_CLOUD=1 # LOCAL_DBGATE_IDENTITY=1 # CLOUD_UPGRADE_FILE=c:\test\upg\upgrade.zip diff --git a/packages/api/src/controllers/auth.js b/packages/api/src/controllers/auth.js index 363edfc2b..ca373363a 100644 --- a/packages/api/src/controllers/auth.js +++ b/packages/api/src/controllers/auth.js @@ -13,7 +13,7 @@ const { } = require('../auth/authProvider'); const storage = require('./storage'); const { decryptPasswordString } = require('../utility/crypting'); -const { createDbGateIdentitySession, startCloudTokenChecking } = require('../utility/cloudIntf'); +const { createDbGateIdentitySession, startCloudTokenChecking, readCloudTokenHolder } = require('../utility/cloudIntf'); const socket = require('../utility/socket'); const logger = getLogger('auth'); @@ -138,8 +138,8 @@ module.exports = { }, createCloudLoginSession_meta: true, - async createCloudLoginSession({ client }) { - const res = await createDbGateIdentitySession(client); + async createCloudLoginSession({ client, redirectUri }) { + const res = await createDbGateIdentitySession(client, redirectUri); startCloudTokenChecking(res.sid, tokenHolder => { socket.emit('got-cloud-token', tokenHolder); socket.emitChanged('cloud-content-changed'); @@ -148,5 +148,11 @@ module.exports = { return res; }, + cloudLoginRedirected_meta: true, + async cloudLoginRedirected({ sid }) { + const tokenHolder = await readCloudTokenHolder(sid); + return tokenHolder; + }, + authMiddleware, }; diff --git a/packages/api/src/controllers/config.js b/packages/api/src/controllers/config.js index 057f6ff16..1eaeb893e 100644 --- a/packages/api/src/controllers/config.js +++ b/packages/api/src/controllers/config.js @@ -118,6 +118,7 @@ module.exports = { supportCloudAutoUpgrade: !!process.env.CLOUD_UPGRADE_FILE, allowPrivateCloud: platformInfo.isElectron || !!process.env.ALLOW_DBGATE_PRIVATE_CLOUD, ...currentVersion, + redirectToDbGateCloudLogin: !!process.env.REDIRECT_TO_DBGATE_CLOUD_LOGIN, }; return configResult; diff --git a/packages/api/src/utility/cloudIntf.js b/packages/api/src/utility/cloudIntf.js index 2d8dcf75c..9b4733fed 100644 --- a/packages/api/src/utility/cloudIntf.js +++ b/packages/api/src/utility/cloudIntf.js @@ -34,11 +34,12 @@ const DBGATE_CLOUD_URL = process.env.LOCAL_DBGATE_CLOUD ? 'https://cloud.dbgate.udolni.net' : 'https://cloud.dbgate.io'; -async function createDbGateIdentitySession(client) { +async function createDbGateIdentitySession(client, redirectUri) { const resp = await axios.default.post( `${DBGATE_IDENTITY_URL}/api/create-session`, { client, + redirectUri, }, { headers: { @@ -70,7 +71,7 @@ function startCloudTokenChecking(sid, callback) { }); // console.log('CHECK RESP:', resp.data); - if (resp.data.email) { + if (resp.data?.email) { clearInterval(interval); callback(resp.data); } @@ -80,6 +81,18 @@ function startCloudTokenChecking(sid, callback) { }, 500); } +async function readCloudTokenHolder(sid) { + const resp = await axios.default.get(`${DBGATE_IDENTITY_URL}/api/get-token/${sid}`, { + headers: { + ...getLicenseHttpHeaders(), + }, + }); + if (resp.data?.email) { + return resp.data; + } + return null; +} + async function loadCloudFiles() { try { const fileContent = await fs.readFile(path.join(datadir(), 'cloud-files.jsonl'), 'utf-8'); @@ -396,4 +409,5 @@ module.exports = { loadCachedCloudConnection, putCloudContent, removeCloudCachedConnection, + readCloudTokenHolder, }; diff --git a/packages/web/src/clientAuth.ts b/packages/web/src/clientAuth.ts index 14fd7c184..7d1af7bb0 100644 --- a/packages/web/src/clientAuth.ts +++ b/packages/web/src/clientAuth.ts @@ -3,6 +3,7 @@ import { getConfig } from './utility/metadataLoaders'; import { isAdminPage } from './utility/pageDefs'; import getElectron from './utility/getElectron'; import { isProApp } from './utility/proTools'; +import { cloudSigninTokenHolder, selectedWidget } from './stores'; export function isOauthCallback() { const params = new URLSearchParams(location.search); @@ -114,6 +115,12 @@ export function handleOauthCallback() { return true; } + const cloudSid = params.get('dbgate-cloud-sid'); + if (cloudSid) { + sessionStorage.setItem('dbgate-cloud-sid', cloudSid); + internalRedirectTo(`/`); + } + return false; } @@ -187,6 +194,18 @@ export async function handleAuthOnStartup(config) { } } + async function checkDbGateCloudLogin() { + const sid = sessionStorage.getItem('dbgate-cloud-sid'); + if (sid) { + const tokenHolder = await apiCall('auth/cloud-login-redirected', { sid }); + if (tokenHolder) { + sessionStorage.removeItem('dbgate-cloud-sid'); + cloudSigninTokenHolder.set(tokenHolder); + selectedWidget.set('cloud-private'); + } + } + } + if (page == 'error') return; if (checkConfigError()) return; @@ -199,6 +218,7 @@ export async function handleAuthOnStartup(config) { if (page == 'license' || page == 'admin-license') return; if (checkTrialDaysLeft()) return; if (checkInvalidLicense()) return; + checkDbGateCloudLogin(); // if (config.configurationError) { // internalRedirectTo(`/error.html`); diff --git a/packages/web/src/utility/api.ts b/packages/web/src/utility/api.ts index 9a248c762..14ca14985 100644 --- a/packages/web/src/utility/api.ts +++ b/packages/web/src/utility/api.ts @@ -289,8 +289,8 @@ export function installNewVolatileConnectionListener() { } export function installNewCloudTokenListener() { + // console.log('HOLDER', tokenHolder); apiOn('got-cloud-token', async tokenHolder => { - // console.log('HOLDER', tokenHolder); cloudSigninTokenHolder.set(tokenHolder); selectedWidget.set('cloud-private'); }); diff --git a/packages/web/src/widgets/WidgetIconPanel.svelte b/packages/web/src/widgets/WidgetIconPanel.svelte index eead969f2..ead3e939e 100644 --- a/packages/web/src/widgets/WidgetIconPanel.svelte +++ b/packages/web/src/widgets/WidgetIconPanel.svelte @@ -135,8 +135,16 @@ } async function handleOpenCloudLogin() { - const { url, sid } = await apiCall('auth/create-cloud-login-session', { client: getElectron() ? 'app' : 'web' }); - openWebLink(url, true); + const useRedirect = getCurrentConfig()?.redirectToDbGateCloudLogin; + const { url, sid } = await apiCall('auth/create-cloud-login-session', { + client: getElectron() ? 'app' : 'web', + redirectUri: useRedirect ? location.origin + location.pathname : undefined, + }); + if (useRedirect) { + location.href = url; + } else { + openWebLink(url, true); + } }