diff --git a/packages/api/src/auth/authProvider.js b/packages/api/src/auth/authProvider.js index ecffeccd1..93faa5c5c 100644 --- a/packages/api/src/auth/authProvider.js +++ b/packages/api/src/auth/authProvider.js @@ -26,6 +26,10 @@ class AuthProviderBase { return login; } + isUserLoggedIn(req) { + return !!req.user || !!req.auth; + } + getCurrentPermissions(req) { const login = this.getCurrentLogin(req); const permissions = process.env[`LOGIN_PERMISSIONS_${login}`]; diff --git a/packages/api/src/controllers/auth.js b/packages/api/src/controllers/auth.js index 1193dc435..e52a32ffe 100644 --- a/packages/api/src/controllers/auth.js +++ b/packages/api/src/controllers/auth.js @@ -23,12 +23,14 @@ function unauthorizedResponse(req, res, text) { function authMiddleware(req, res, next) { const SKIP_AUTH_PATHS = [ '/config/get', + '/config/get-settings', '/auth/oauth-token', '/auth/login', '/stream', 'storage/get-connections-for-login-page', '/connections/dblogin', '/connections/dblogin-auth', + '/connections/dblogin-auth-token', ]; // console.log('********************* getAuthProvider()', getAuthProvider()); diff --git a/packages/api/src/controllers/config.js b/packages/api/src/controllers/config.js index d8e7f72bf..f551a5153 100644 --- a/packages/api/src/controllers/config.js +++ b/packages/api/src/controllers/config.js @@ -33,6 +33,7 @@ module.exports = { const permissions = authProvider.getCurrentPermissions(req); const isLoginForm = authProvider.isLoginForm(); const additionalConfigProps = authProvider.getAdditionalConfigProps(); + const isUserLoggedIn = authProvider.isUserLoggedIn(req); const singleConid = authProvider.getSingleConnectionId(req); @@ -44,6 +45,7 @@ module.exports = { runAsPortal: !!connections.portalConnections, singleDbConnection: connections.singleDbConnection, singleConnection: singleConnection, + isUserLoggedIn, // hideAppEditor: !!process.env.HIDE_APP_EDITOR, allowShellConnection: platformInfo.allowShellConnection, allowShellScripting: platformInfo.allowShellScripting, diff --git a/packages/api/src/controllers/connections.js b/packages/api/src/controllers/connections.js index 831c849ce..193d5fd5b 100644 --- a/packages/api/src/controllers/connections.js +++ b/packages/api/src/controllers/connections.js @@ -412,6 +412,22 @@ module.exports = { } }, + dbloginAuthToken_meta: true, + async dbloginAuthToken({ code, conid, redirectUri }) { + try { + const connection = await this.getCore({ conid }); + const driver = requireEngineDriver(connection); + const accessToken = await driver.getAuthTokenFromCode(connection, { code, redirectUri }); + const volatile = await this.saveVolatile({ conid, accessToken }); + const authProvider = getAuthProvider(); + const resp = await authProvider.login(null, null, { conid: volatile._id }); + return resp; + } catch (err) { + logger.error({ err }, 'Error getting DB token'); + return { error: err.message }; + } + }, + dbloginAuth_meta: true, async dbloginAuth({ conid, user, password }) { if (user || password) { diff --git a/packages/web/src/LoginPage.svelte b/packages/web/src/LoginPage.svelte index fe36b1e0c..ed534b482 100644 --- a/packages/web/src/LoginPage.svelte +++ b/packages/web/src/LoginPage.svelte @@ -99,17 +99,17 @@ value="Open database login page" on:click={async e => { const state = `dbg-dblogin:${strmid}:${selectedConnection?.conid}`; - localStorage.setItem('dbloginState', state); - openWebLink( - `connections/dblogin?conid=${selectedConnection?.conid}&state=${encodeURIComponent(state)}&redirectUri=${ - location.origin + location.pathname - }` - ); - // internalRedirectTo( + sessionStorage.setItem('dbloginAuthState', state); + // openWebLink( // `connections/dblogin?conid=${selectedConnection?.conid}&state=${encodeURIComponent(state)}&redirectUri=${ // location.origin + location.pathname // }` // ); + internalRedirectTo( + `connections/dblogin?conid=${selectedConnection?.conid}&state=${encodeURIComponent(state)}&redirectUri=${ + location.origin + location.pathname + }` + ); }} /> {:else if selectedConnection} diff --git a/packages/web/src/clientAuth.ts b/packages/web/src/clientAuth.ts index 3cb6be1db..69041e99a 100644 --- a/packages/web/src/clientAuth.ts +++ b/packages/web/src/clientAuth.ts @@ -22,6 +22,19 @@ export function isDbLoginCallback() { ); } +export function isDbLoginAuthCallback() { + const params = new URLSearchParams(location.search); + const sentCode = params.get('code'); + const sentState = params.get('state'); + + return ( + sentCode && + sentState && + sentState.startsWith('dbg-dblogin:') && + sentState == sessionStorage.getItem('dbloginAuthState') + ); +} + export function handleOauthCallback() { const params = new URLSearchParams(location.search); const sentCode = params.get('code'); @@ -37,7 +50,7 @@ export function handleOauthCallback() { if (accessToken) { console.log('Settings access token from OAUTH'); localStorage.setItem('accessToken', accessToken); - internalRedirectTo('/'); + internalRedirectTo('?'); } else { console.log('Error when processing OAUTH callback', error || errorMessage); internalRedirectTo(`?page=not-logged&error=${error || errorMessage}`); @@ -60,7 +73,29 @@ export function handleOauthCallback() { if (authResp.success) { window.close(); } else if (authResp.error) { - internalRedirectTo(`?page=error&error=${encodeURIComponent(authResp)}`); + internalRedirectTo(`?page=error&error=${encodeURIComponent(authResp.error)}`); + } else { + internalRedirectTo(`?page=error`); + } + }); + + return true; + } + + if (isDbLoginAuthCallback()) { + const [_prefix, strmid, conid] = sessionStorage.getItem('dbloginAuthState').split(':'); + sessionStorage.removeItem('dbloginAuthState'); + + apiCall('connections/dblogin-auth-token', { + code: sentCode, + conid, + redirectUri: location.origin + location.pathname, + }).then(authResp => { + if (authResp.accessToken) { + localStorage.setItem('accessToken', authResp.accessToken); + internalRedirectTo('?'); + } else if (authResp.error) { + internalRedirectTo(`?page=error&error=${encodeURIComponent(authResp.error)}`); } else { internalRedirectTo(`?page=error`); } diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index 893b63a7d..e9c0296a4 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -551,7 +551,7 @@ registerCommand({ id: 'app.logout', category: 'App', name: 'Logout', - testEnabled: () => getCurrentConfig()?.login != null, + testEnabled: () => getCurrentConfig()?.isUserLoggedIn, onClick: doLogout, }); @@ -559,7 +559,7 @@ registerCommand({ id: 'app.disconnect', category: 'App', name: 'Disconnect', - testEnabled: () => getCurrentConfig()?.singleConnection != null, + testEnabled: () => getCurrentConfig()?.singleConnection != null && !getCurrentConfig()?.isUserLoggedIn, onClick: () => disconnectServerConnection(getCurrentConfig()?.singleConnection?._id), }); @@ -873,7 +873,6 @@ registerCommand({ onClick: () => showModal(UploadErrorModal), }); - const electron = getElectron(); if (electron) { electron.addEventListener('run-command', (e, commandId) => runCommand(commandId));