diff --git a/packages/api/src/controllers/connections.js b/packages/api/src/controllers/connections.js index 19b48b867..2dc50073e 100644 --- a/packages/api/src/controllers/connections.js +++ b/packages/api/src/controllers/connections.js @@ -386,10 +386,18 @@ module.exports = { method: 'get', }, async dblogin(req, res) { - const { conid } = req.query; + const { conid, state, redirectUri } = req.query; const connection = await this.getCore({ conid }); const driver = requireEngineDriver(connection); - const authUrl = await driver.getRedirectAuthUrl(connection); + const authUrl = await driver.getRedirectAuthUrl(connection, { redirectUri, state }); res.redirect(authUrl); }, + + dbloginToken_meta: true, + async dbloginToken({ code, conid, redirectUri }) { + const connection = await this.getCore({ conid }); + const driver = requireEngineDriver(connection); + const token = await driver.getAuthTokenFromCode(connection, { code, redirectUri }); + console.log('******************************** WE HAVE ACCESS TOKEN', token); + }, }; diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 176e2059b..e8bfc8155 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -149,7 +149,8 @@ export interface EngineDriver { summaryCommand(pool, command, row): Promise; startProfiler(pool, options): Promise; stopProfiler(pool, profiler): Promise; - getRedirectAuthUrl(connection): Promise; + getRedirectAuthUrl(connection, options): Promise; + getAuthTokenFromCode(connection, options): Promise; analyserClass?: any; dumperClass?: any; diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index ed14a91bb..a7ffe82ad 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -20,7 +20,7 @@ import getElectron from './utility/getElectron'; import AppStartInfo from './widgets/AppStartInfo.svelte'; import SettingsListener from './utility/SettingsListener.svelte'; - import { handleAuthOnStartup, handleOauthCallback } from './clientAuth'; + import { handleAuthOnStartup } from './clientAuth'; export let isAdminPage = false; diff --git a/packages/web/src/clientAuth.ts b/packages/web/src/clientAuth.ts index b471c517a..83077abcd 100644 --- a/packages/web/src/clientAuth.ts +++ b/packages/web/src/clientAuth.ts @@ -12,6 +12,16 @@ export function isOauthCallback() { ); } +export function isDbLoginCallback() { + const params = new URLSearchParams(location.search); + const sentCode = params.get('code'); + const sentState = params.get('state'); + + return ( + sentCode && sentState && sentState.startsWith('dbg-dblogin:') && sentState == localStorage.getItem('dbloginState') + ); +} + export function handleOauthCallback() { const params = new URLSearchParams(location.search); const sentCode = params.get('code'); @@ -37,6 +47,32 @@ export function handleOauthCallback() { return true; } + console.log('****************** IS DB LOGIN TEST'); + if (isDbLoginCallback()) { + console.log('****************** IS DB LOGIN TRUE'); + const conid = localStorage.getItem('dbloginState').split('@')[1]; + localStorage.removeItem('dbloginState'); + + apiCall('connections/dblogin-token', { + code: sentCode, + conid, + redirectUri: location.origin + location.pathname, + }).then(authResp => { + const { accessToken, error, errorMessage } = authResp; + + if (accessToken) { + console.log('Settings access token from OAUTH'); + localStorage.setItem('accessToken', accessToken); + internalRedirectTo('/'); + } else { + console.log('Error when processing OAUTH callback', error || errorMessage); + internalRedirectTo(`?page=not-logged&error=${error || errorMessage}`); + } + }); + + return true; + } + return false; } diff --git a/packages/web/src/utility/api.ts b/packages/web/src/utility/api.ts index da33d9c3e..d61f94601 100644 --- a/packages/web/src/utility/api.ts +++ b/packages/web/src/utility/api.ts @@ -12,6 +12,7 @@ import uuidv1 from 'uuid/v1'; import { openWebLink } from './exportFileTools'; export const strmid = uuidv1(); +const privateApiState = Math.random().toString().substr(2); let eventSource; let apiLogging = false; @@ -65,7 +66,13 @@ function processApiResponse(route, args, resp) { if (resp?.missingCredentials) { if (resp.detail.redirectToDbLogin) { - openWebLink(`connections/dblogin?conid=${resp.detail.conid}`); + const state = `dbg-dblogin:${privateApiState}@${resp.detail.conid}`; + localStorage.setItem('dbloginState', state); + openWebLink( + `connections/dblogin?conid=${resp.detail.conid}&state=${encodeURIComponent(state)}&redirectUri=${ + location.origin + location.pathname + }` + ); } else if (!isDatabaseLoginVisible()) { showModal(DatabaseLoginModal, resp.detail); } diff --git a/plugins/dbgate-plugin-mssql/src/backend/azureAuth.js b/plugins/dbgate-plugin-mssql/src/backend/azureAuth.js index a13bb06e7..2394c928c 100644 --- a/plugins/dbgate-plugin-mssql/src/backend/azureAuth.js +++ b/plugins/dbgate-plugin-mssql/src/backend/azureAuth.js @@ -6,7 +6,12 @@ async function azureGetRedirectAuthUrl(connection) { return null; } +async function azureGetAuthTokenFromCode(connection, code) { + return null; +} + module.exports = { getAzureAuthTypes, azureGetRedirectAuthUrl, + azureGetAuthTokenFromCode, }; diff --git a/plugins/dbgate-plugin-mssql/src/backend/driver.js b/plugins/dbgate-plugin-mssql/src/backend/driver.js index dce7e6138..1e688254e 100644 --- a/plugins/dbgate-plugin-mssql/src/backend/driver.js +++ b/plugins/dbgate-plugin-mssql/src/backend/driver.js @@ -8,7 +8,7 @@ const AsyncLock = require('async-lock'); const nativeDriver = require('./nativeDriver'); const lock = new AsyncLock(); const { tediousConnect, tediousQueryCore, tediousReadQuery, tediousStream } = require('./tediousDriver'); -const { getAzureAuthTypes, azureGetRedirectAuthUrl } = require('./azureAuth'); +const { getAzureAuthTypes, azureGetRedirectAuthUrl, azureGetAuthTokenFromCode } = require('./azureAuth'); const { nativeConnect, nativeQueryCore, nativeReadQuery, nativeStream } = nativeDriver; let requireMsnodesqlv8; @@ -125,9 +125,12 @@ const driver = { const { rows } = await this.query(pool, 'SELECT name FROM sys.databases order by name'); return rows; }, - getRedirectAuthUrl(connection) { - return azureGetRedirectAuthUrl(connection); - } + getRedirectAuthUrl(connection, options) { + return azureGetRedirectAuthUrl(connection, options); + }, + getAuthTokenFromCode(connection, options) { + return azureGetAuthTokenFromCode(connection, options); + }, }; driver.initialize = dbgateEnv => {