diff --git a/packages/api/src/auth/authProvider.js b/packages/api/src/auth/authProvider.js index 7503feee4..2b0e69da7 100644 --- a/packages/api/src/auth/authProvider.js +++ b/packages/api/src/auth/authProvider.js @@ -1,7 +1,7 @@ const { getTokenSecret, getTokenLifetime } = require('./authCommon'); const _ = require('lodash'); const axios = require('axios'); -const { getLogger } = require('dbgate-tools'); +const { getLogger, getPredefinedPermissions } = require('dbgate-tools'); const AD = require('activedirectory2').promiseWrapper; const jwt = require('jsonwebtoken'); @@ -12,7 +12,15 @@ class AuthProviderBase { amoid = 'none'; async login(login, password, options = undefined) { - return {}; + return { + accessToken: jwt.sign( + { + amoid: this.amoid, + }, + getTokenSecret(), + { expiresIn: getTokenLifetime() } + ), + }; } shouldAuthorizeApi() { @@ -57,6 +65,7 @@ class AuthProviderBase { toJson() { return { amoid: this.amoid, + workflowType: 'anonymous', }; } } @@ -127,12 +136,19 @@ class OAuthProvider extends AuthProviderBase { oauthLogout: process.env.OAUTH_LOGOUT, }; } + + toJson() { + return { + ...super.toJson(), + workflowType: 'redirect', + }; + } } class ADProvider extends AuthProviderBase { amoid = 'ad'; - async login(login, password) { + async login(login, password, options = undefined) { const adConfig = { url: process.env.AD_URL, baseDN: process.env.AD_BASEDN, @@ -152,7 +168,14 @@ class ADProvider extends AuthProviderBase { return { error: `Username ${login} not allowed to log in` }; } return { - accessToken: jwt.sign({ login }, getTokenSecret(), { expiresIn: getTokenLifetime() }), + accessToken: jwt.sign( + { + amoid: this.amoid, + login, + }, + getTokenSecret(), + { expiresIn: getTokenLifetime() } + ), }; } catch (e) { return { error: 'Login failed' }; @@ -166,15 +189,29 @@ class ADProvider extends AuthProviderBase { isLoginForm() { return !process.env.BASIC_AUTH; } + + toJson() { + return { + ...super.toJson(), + workflowType: 'credentials', + }; + } } class LoginsProvider extends AuthProviderBase { amoid = 'logins'; - async login(login, password) { + async login(login, password, options = undefined) { if (password == process.env[`LOGIN_PASSWORD_${login}`]) { return { - accessToken: jwt.sign({ login }, getTokenSecret(), { expiresIn: getTokenLifetime() }), + accessToken: jwt.sign( + { + amoid: this.amoid, + login, + }, + getTokenSecret(), + { expiresIn: getTokenLifetime() } + ), }; } return { error: 'Invalid credentials' }; @@ -187,6 +224,13 @@ class LoginsProvider extends AuthProviderBase { isLoginForm() { return !process.env.BASIC_AUTH; } + + toJson() { + return { + ...super.toJson(), + workflowType: 'credentials', + }; + } } class DenyAllProvider extends AuthProviderBase { @@ -196,9 +240,16 @@ class DenyAllProvider extends AuthProviderBase { return true; } - async login(login, password) { + async login(login, password, options = undefined) { return { error: 'Login not allowed' }; } + + toJson() { + return { + ...super.toJson(), + workflowType: 'credentials', + }; + } } function hasEnvLogins() { diff --git a/packages/web/src/LoginPage.svelte b/packages/web/src/LoginPage.svelte index a1b1f31dd..79d6c071d 100644 --- a/packages/web/src/LoginPage.svelte +++ b/packages/web/src/LoginPage.svelte @@ -30,6 +30,9 @@ $: selectedConnection = availableConnections?.find(x => x.conid == $values.databaseServer); + $: selectedProvider = availableProviders?.find(x => x.amoid == $values.amoid); + $: workflowType = selectedProvider?.workflowType ?? 'credentials'; + async function loadAvailableServers(amoid) { if (amoid) { availableConnections = await apiCall('storage/get-connections-for-login-page', { amoid }); @@ -80,7 +83,7 @@ /> {/if} - {#if !isAdminPage && availableConnections} + {#if !isAdminPage && availableConnections && workflowType == 'database'} {/if} {:else} - {#if !isAdminPage} + {#if !isAdminPage && workflowType == 'credentials'} {/if} - + {#if workflowType == 'credentials'} + + {/if} {/if} {#if isAdminPage && $config && !$config.isAdminLoginForm} @@ -173,31 +178,38 @@ /> {:else} { enableApi(); - const resp = await apiCall('auth/login', { - amoid: $values.amoid, - isAdminPage, - ...e.detail, - }); - if (resp.error) { - internalRedirectTo( - `/?page=not-logged&error=${encodeURIComponent(resp.error)}&is-admin=${isAdminPage ? 'true' : ''}` - ); - return; - } - const { accessToken } = resp; - if (accessToken) { - localStorage.setItem(isAdminPage ? 'adminAccessToken' : 'accessToken', accessToken); - if (isAdminPage) { - internalRedirectTo('/?page=admin'); - } else { - internalRedirectTo('/'); + + if (isAdminPage || workflowType == 'credentials' || workflowType == 'anonymous') { + const resp = await apiCall('auth/login', { + amoid: $values.amoid, + isAdminPage, + ...e.detail, + }); + if (resp.error) { + internalRedirectTo( + `/?page=not-logged&error=${encodeURIComponent(resp.error)}&is-admin=${isAdminPage ? 'true' : ''}` + ); + return; } - return; + const { accessToken } = resp; + if (accessToken) { + localStorage.setItem(isAdminPage ? 'adminAccessToken' : 'accessToken', accessToken); + if (isAdminPage) { + internalRedirectTo('/?page=admin'); + } else { + internalRedirectTo('/'); + } + return; + } + internalRedirectTo(`/?page=not-logged`); } - internalRedirectTo(`/?page=not-logged`); }} /> {/if}