diff --git a/.github/workflows/jest-tests-runner.yml b/.github/workflows/jest-tests-runner.yml new file mode 100644 index 0000000000..562f215b03 --- /dev/null +++ b/.github/workflows/jest-tests-runner.yml @@ -0,0 +1,31 @@ +name: Run Jest Tests + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the "devel" branch + pull_request: + branches: [ "devel" ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + run-jest-tests: + # The type of runner that the job will run on + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./webapp + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '16' + - run: npm install --legacy-peer-deps + - run: npm install lerna -g + - run: lerna bootstrap + - run: lerna run test --no-bail --stream -- --reporters default github-actions + diff --git a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF index 1e1baa83f2..9f8a4013cd 100644 --- a/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.model;singleton:=true -Bundle-Version: 1.0.11.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.12.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.model/pom.xml b/server/bundles/io.cloudbeaver.model/pom.xml index 7009a3b182..8f3bc9174f 100644 --- a/server/bundles/io.cloudbeaver.model/pom.xml +++ b/server/bundles/io.cloudbeaver.model/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.model - 1.0.11-SNAPSHOT + 1.0.12-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java index 3b727d3eee..4b9edeca46 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/auth/provider/fa/AbstractSessionFederated.java @@ -67,6 +67,7 @@ public abstract class AbstractSessionFederated implements SMSessionFederated { return parentSession.getSingletonProject(); } + @Override public void close() { // do nothing } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java index 4a65801d27..5d638eab22 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerProject.java @@ -24,12 +24,14 @@ import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBIcon; import org.jkiss.dbeaver.model.DBPImage; import org.jkiss.dbeaver.model.DBPObject; +import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.auth.SMSessionContext; import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.rm.RMController; import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.model.rm.RMResource; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.utils.CommonUtils; import java.util.ArrayList; import java.util.List; @@ -114,6 +116,21 @@ public class DBNResourceManagerProject extends DBNAbstractResourceManagerNode { return getNodeName(); } + + @Override + public DBPProject getOwnerProject() { + List globalProjects = getModel().getModelProjects(); + if (globalProjects == null) { + return null; + } + for (DBPProject modelProject : globalProjects) { + if (CommonUtils.equalObjects(modelProject.getId(), project.getId())) { + return modelProject; + } + } + return null; + } + @Nullable @Override public DBPObject getObjectDetails(@NotNull DBRProgressMonitor monitor, @NotNull SMSessionContext sessionContext, @NotNull Object dataSource) throws DBException { diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java index 120b805572..772eb19714 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerResource.java @@ -24,6 +24,7 @@ import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBIcon; import org.jkiss.dbeaver.model.DBPImage; import org.jkiss.dbeaver.model.DBPObject; +import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.auth.SMSessionContext; import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.rm.RMController; @@ -165,6 +166,11 @@ public class DBNResourceManagerResource extends DBNAbstractResourceManagerNode { return resource; } + @Override + public DBPProject getOwnerProject() { + return getParentNode().getOwnerProject(); + } + public RMResource getResource() { return resource; } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index d836612a45..9d45432cac 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -545,7 +545,7 @@ public class LocalResourceController implements RMController { if (Files.exists(path)) { try { project.setCreateTime( - OffsetDateTime.ofInstant(Files.getLastModifiedTime(path).toInstant(), ZoneId.of("UTC"))); + OffsetDateTime.ofInstant(Files.getLastModifiedTime(path).toInstant(), ZoneId.of("UTC")).toInstant().toEpochMilli()); } catch (IOException e) { log.error(e); } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java index b2dcfb7cec..c0f0872e8f 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java @@ -584,14 +584,19 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, } } - public void close() throws DBException { + @Override + public void close() { try { resetNavigationModel(); resetSessionCache(); } catch (Throwable e) { log.error(e); } - clearAuthTokens(); + try { + clearAuthTokens(); + } catch (Exception e) { + log.error("Error closing web session tokens"); + } this.sessionAuthContext.close(); this.userContext.setUser(null); @@ -599,6 +604,7 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, this.defaultProject.dispose(); this.defaultProject = null; } + super.close(); } private void clearAuthTokens() throws DBException { @@ -959,6 +965,11 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, return userContext.getActiveUserCredentials(); } + @Override + public void refreshSMSession() throws DBException { + userContext.refreshSMSession(); + } + public VirtualProjectImpl getProjectById(@Nullable String projectId) { if (projectId == null) { return defaultProject; diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java index b943f87412..fa51e53d89 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebUserContext.java @@ -47,6 +47,7 @@ public class WebUserContext implements SMCredentialsProvider { private Set userPermissions; private SMCredentials smCredentials = null; private String smSessionId; + private String refreshToken; private SMController securityController; private SMAdminController adminSecurityController; @@ -64,7 +65,7 @@ public class WebUserContext implements SMCredentialsProvider { * @param smAuthInfo - auth info from security manager * @throws DBException - if user already authorized and new token come from another user */ - public void refresh(SMAuthInfo smAuthInfo) throws DBException { + public synchronized void refresh(SMAuthInfo smAuthInfo) throws DBException { if (smAuthInfo.getAuthStatus() != SMAuthStatus.SUCCESS) { throw new DBCException("Authorization did not complete successfully"); } @@ -77,7 +78,12 @@ public class WebUserContext implements SMCredentialsProvider { if (isNonAnonymousUserAuthorized && isSessionChanged && !Objects.equals(getUserId(), authPermissions.getUserId())) { throw new DBCException("Another user is already logged in"); } - this.smCredentials = new SMCredentials(smAuthInfo.getSmAuthToken(), authPermissions.getUserId(), authPermissions.getPermissions()); + this.smCredentials = new SMCredentials( + smAuthInfo.getSmAuthToken(), + authPermissions.getUserId(), + authPermissions.getPermissions() + ); + this.refreshToken = smAuthInfo.getSmRefreshToken(); this.userPermissions = authPermissions.getPermissions(); this.securityController = application.getSecurityController(this); this.adminSecurityController = application.getAdminSecurityController(this); @@ -89,10 +95,23 @@ public class WebUserContext implements SMCredentialsProvider { } + public synchronized void refreshSMSession() throws DBException { + if (smCredentials == null || refreshToken == null) { + return; + } + var newTokens = securityController.refreshSession(refreshToken); + this.refreshToken = newTokens.getSmRefreshToken(); + this.smCredentials = new SMCredentials( + newTokens.getSmAccessToken(), + smCredentials.getUserId(), + smCredentials.getPermissions() + ); + } + /** * reset the state as if the user is not logged in */ - public void reset() throws DBException { + public synchronized void reset() throws DBException { if (this.smCredentials != null) { this.securityController.logout(); } @@ -155,8 +174,8 @@ public class WebUserContext implements SMCredentialsProvider { } if (userPermissions != null && !userPermissions.isEmpty() && - !userPermissions.contains(DBWConstants.PERMISSION_PUBLIC)) - { + !userPermissions.contains(DBWConstants.PERMISSION_PUBLIC) + ) { userPermissions.add(DBWConstants.PERMISSION_PUBLIC); } } diff --git a/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF index 7f6fa1e8ff..ff87107d8f 100644 --- a/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.product.ce/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.product.ce;singleton:=true -Bundle-Version: 22.1.5.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 22.2.0.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.product.ce/pom.xml b/server/bundles/io.cloudbeaver.product.ce/pom.xml index 488af4c71d..2fa1115bbd 100644 --- a/server/bundles/io.cloudbeaver.product.ce/pom.xml +++ b/server/bundles/io.cloudbeaver.product.ce/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.product.ce - 22.1.5-SNAPSHOT + 22.2.0-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF index ebd677867f..1f103b7798 100644 --- a/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.resources.drivers.base/META-INF/MANIFEST.MF @@ -2,8 +2,8 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Base JDBC drivers Bundle-SymbolicName: io.cloudbeaver.resources.drivers.base;singleton:=true -Bundle-Version: 1.0.56.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.57.qualifier +Bundle-Release-Date: 20220905 Bundle-Vendor: DBeaver Corp Bundle-ActivationPolicy: lazy Automatic-Module-Name: io.cloudbeaver.resources.drivers.base diff --git a/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml b/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml index e4560a2196..c36ec25313 100644 --- a/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml +++ b/server/bundles/io.cloudbeaver.resources.drivers.base/pom.xml @@ -9,6 +9,6 @@ ../ io.cloudbeaver.resources.drivers.base - 1.0.56-SNAPSHOT + 1.0.57-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF index e8aed83934..026ed8d394 100644 --- a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.server;singleton:=true -Bundle-Version: 22.1.5.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 22.2.0.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: io.cloudbeaver.server.CBPlatformActivator diff --git a/server/bundles/io.cloudbeaver.server/pom.xml b/server/bundles/io.cloudbeaver.server/pom.xml index cc4662e7b1..7fb53e2055 100644 --- a/server/bundles/io.cloudbeaver.server/pom.xml +++ b/server/bundles/io.cloudbeaver.server/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.server - 22.1.5-SNAPSHOT + 22.2.0-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java index 0991189fa2..b4d5f967cf 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/session/WebSessionManager.java @@ -181,11 +181,7 @@ public class WebSessionManager { for (WebSession session : expiredList) { log.debug("> Expire session '" + session.getSessionId() + "'"); - try { - session.close(); - } catch (DBException e) { - log.debug("Failed close session:" + session.getSessionId(), e); - } + session.close(); } } diff --git a/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF index a15d3aef4d..9aff6c1fc9 100644 --- a/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.service.admin/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.service.admin;singleton:=true -Bundle-Version: 1.0.55.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.56.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.service.admin/pom.xml b/server/bundles/io.cloudbeaver.service.admin/pom.xml index 5ee07f5de8..9e6e9dbc8d 100644 --- a/server/bundles/io.cloudbeaver.service.admin/pom.xml +++ b/server/bundles/io.cloudbeaver.service.admin/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.service.admin - 1.0.55-SNAPSHOT + 1.0.56-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF index a149955cfd..103219c6b1 100644 --- a/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.service.auth/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.service.auth;singleton:=true -Bundle-Version: 1.0.55.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.56.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.service.auth/pom.xml b/server/bundles/io.cloudbeaver.service.auth/pom.xml index fb90ad4ee1..7d314cd0dc 100644 --- a/server/bundles/io.cloudbeaver.service.auth/pom.xml +++ b/server/bundles/io.cloudbeaver.service.auth/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.service.auth - 1.0.55-SNAPSHOT + 1.0.56-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF index da7aa9a73d..bee4d39699 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.service.data.transfer/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.service.data.transfer;singleton:=true -Bundle-Version: 1.0.56.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.57.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml b/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml index 1a22d17b9e..b3ef67417c 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml +++ b/server/bundles/io.cloudbeaver.service.data.transfer/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.service.data.transfer - 1.0.56-SNAPSHOT + 1.0.57-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF index f6968730e8..88ea4b695a 100644 --- a/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.service.metadata/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.service.metadata;singleton:=true -Bundle-Version: 1.0.59.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.60.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.service.metadata/pom.xml b/server/bundles/io.cloudbeaver.service.metadata/pom.xml index 9458a19040..637fdd40d9 100644 --- a/server/bundles/io.cloudbeaver.service.metadata/pom.xml +++ b/server/bundles/io.cloudbeaver.service.metadata/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.service.metadata - 1.0.59-SNAPSHOT + 1.0.60-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF index 7ab5e04ae6..d6bf417a02 100644 --- a/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.service.rm/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: %Bundle-Vendor Bundle-Name: %Bundle-Name Bundle-SymbolicName: io.cloudbeaver.service.rm;singleton:=true -Bundle-Version: 1.0.8.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.9.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.service.rm/pom.xml b/server/bundles/io.cloudbeaver.service.rm/pom.xml index 0f5d35908c..d10ff14b29 100644 --- a/server/bundles/io.cloudbeaver.service.rm/pom.xml +++ b/server/bundles/io.cloudbeaver.service.rm/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.service.rm - 1.0.8-SNAPSHOT + 1.0.9-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF index 3be9d3f51e..44d1050332 100644 --- a/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.service.security/META-INF/MANIFEST.MF @@ -3,8 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Vendor: DBeaver Security Sevice Bundle-Vendor: DBeaver Corp Bundle-SymbolicName: io.cloudbeaver.service.security;singleton:=true -Bundle-Version: 1.0.11.qualifier -Bundle-Release-Date: 20220822 +Bundle-Version: 1.0.12.qualifier +Bundle-Release-Date: 20220905 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-ClassPath: . diff --git a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql index 5eb4d7fce1..8861cb445f 100644 --- a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql +++ b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_create.sql @@ -238,12 +238,14 @@ CREATE TABLE CB_SESSION_LOG CREATE TABLE CB_AUTH_TOKEN ( - TOKEN_ID VARCHAR(128) NOT NULL, - SESSION_ID VARCHAR(64) NOT NULL, - USER_ID VARCHAR(128), + TOKEN_ID VARCHAR(128) NOT NULL, + REFRESH_TOKEN_ID VARCHAR(128), + SESSION_ID VARCHAR(64) NOT NULL, + USER_ID VARCHAR(128), - EXPIRATION_TIME TIMESTAMP NOT NULL, - CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + EXPIRATION_TIME TIMESTAMP NOT NULL, + REFRESH_TOKEN_EXPIRATION_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (TOKEN_ID), FOREIGN KEY (SESSION_ID) REFERENCES CB_SESSION (SESSION_ID) ON DELETE CASCADE, diff --git a/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_9.sql b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_9.sql new file mode 100644 index 0000000000..f1a119dd67 --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.security/db/cb_schema_update_9.sql @@ -0,0 +1,5 @@ +ALTER TABLE CB_AUTH_TOKEN + ADD REFRESH_TOKEN_ID VARCHAR(128); + +ALTER TABLE CB_AUTH_TOKEN + ADD REFRESH_TOKEN_EXPIRATION_TIME TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP; \ No newline at end of file diff --git a/server/bundles/io.cloudbeaver.service.security/pom.xml b/server/bundles/io.cloudbeaver.service.security/pom.xml index 992bad4aac..6185d96141 100644 --- a/server/bundles/io.cloudbeaver.service.security/pom.xml +++ b/server/bundles/io.cloudbeaver.service.security/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.service.security - 1.0.11-SNAPSHOT + 1.0.12-SNAPSHOT eclipse-plugin diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java index a88bc75403..9c6b98478b 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/auth/provider/local/LocalAuthSession.java @@ -76,4 +76,9 @@ public class LocalAuthSession implements SMSession { return webSession.getSingletonProject(); } + @Override + public void close() { + + } + } diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java index e0611d1458..a6d2c5de00 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/CBEmbeddedSecurityController.java @@ -27,6 +27,7 @@ import io.cloudbeaver.model.app.WebAuthConfiguration; import io.cloudbeaver.model.session.WebAuthInfo; import io.cloudbeaver.service.security.db.CBDatabase; import io.cloudbeaver.service.security.internal.AuthAttemptSessionInfo; +import io.cloudbeaver.service.security.internal.RefreshTokenInfo; import io.cloudbeaver.utils.WebAppUtils; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; @@ -39,7 +40,9 @@ import org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCTransaction; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.dbeaver.model.security.*; +import org.jkiss.dbeaver.model.security.exception.SMAccessTokenExpiredException; import org.jkiss.dbeaver.model.security.exception.SMException; +import org.jkiss.dbeaver.model.security.exception.SMRefreshTokenExpiredException; import org.jkiss.dbeaver.model.security.user.SMAuthPermissions; import org.jkiss.dbeaver.model.security.user.SMObjectPermissions; import org.jkiss.dbeaver.model.security.user.SMRole; @@ -65,7 +68,8 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen private static final Log log = Log.getLog(CBEmbeddedSecurityController.class); - private static final int TOKEN_HOURS_ALIVE_TIME = 1; + private static final int ACCESS_TOKEN_TTL_IN_MINUTES = 20; + private static final int REFRESH_TOKEN_TTL_IN_HOURS = 24; protected static final String CHAR_BOOL_TRUE = "Y"; protected static final String CHAR_BOOL_FALSE = "N"; @@ -844,10 +848,15 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen try (Connection dbCon = database.openConnection()) { try (JDBCTransaction txn = new JDBCTransaction(dbCon)) { var smSessionId = createSmSession(appSessionId, null, sessionParameters, sessionType, dbCon); - var token = generateAuthToken(smSessionId, null, dbCon); + var smTokens = generateNewSessionToken(smSessionId, null, dbCon); var permissions = getAnonymousUserPermissions(); txn.commit(); - return SMAuthInfo.success(UUID.randomUUID().toString(), token, new SMAuthPermissions(null, smSessionId, permissions), Map.of()); + return SMAuthInfo.success( + UUID.randomUUID().toString(), + smTokens.getSmAccessToken(), + smTokens.getSmRefreshToken(), + new SMAuthPermissions(null, smSessionId, permissions), Map.of() + ); } } catch (SQLException e) { throw new DBException(e.getMessage(), e); @@ -1104,9 +1113,15 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } } - String smToken = findTokenBySmSession(smSessionId); - SMAuthPermissions authPermissions = getTokenPermissions(smToken); - var successAuthStatus = SMAuthInfo.success(authId, smToken, authPermissions, authData); + SMTokens smTokens = findTokenBySmSession(smSessionId); + SMAuthPermissions authPermissions = getTokenPermissions(smTokens.getSmAccessToken()); + var successAuthStatus = SMAuthInfo.success( + authId, + smTokens.getSmAccessToken(), + smTokens.getSmRefreshToken(), + authPermissions, + authData + ); updateAuthStatus(authId, SMAuthStatus.EXPIRED, authData, null, authPermissions.getSessionId()); return successAuthStatus; @@ -1118,10 +1133,29 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen @Override public void logout() throws DBException { var currentUserCreds = getCurrentUserCreds(); - invalidateUserSession(currentUserCreds.getSmToken()); + invalidateUserTokens(currentUserCreds.getSmToken()); } - private void invalidateUserSession(String smToken) throws DBCException { + @Override + public SMTokens refreshSession(@NotNull String refreshToken) throws DBException { + var currentUserCreds = getCurrentUserCreds(); + var currentUserAccessToken = currentUserCreds.getSmToken(); + + var expectedRefreshTokenInfo = findRefreshToken(currentUserAccessToken); + + if (!expectedRefreshTokenInfo.getRefreshToken().equals(refreshToken)) { + throw new SMException("Invalid refresh token"); + } + + try (var dbCon = database.openConnection()) { + invalidateUserTokens(currentUserAccessToken); + return generateNewSessionToken(expectedRefreshTokenInfo.getSessionId(), expectedRefreshTokenInfo.getUserId(), dbCon); + } catch (SQLException e) { + throw new DBException("Error refreshing sm session", e); + } + } + + private void invalidateUserTokens(String smToken) throws DBCException { try (Connection dbCon = database.openConnection()) { JDBCUtils.executeStatement(dbCon, "DELETE FROM CB_AUTH_TOKEN WHERE TOKEN_ID=?", smToken); } catch (SQLException e) { @@ -1137,16 +1171,41 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen return currentUserCreds; } - private String findTokenBySmSession(String smSessionId) throws DBException { + private SMTokens findTokenBySmSession(String smSessionId) throws DBException { try (Connection dbCon = database.openConnection(); - PreparedStatement dbStat = dbCon.prepareStatement("SELECT TOKEN_ID FROM CB_AUTH_TOKEN WHERE SESSION_ID=?"); + PreparedStatement dbStat = dbCon.prepareStatement("SELECT TOKEN_ID, REFRESH_TOKEN_ID FROM CB_AUTH_TOKEN WHERE SESSION_ID=?") ) { dbStat.setString(1, smSessionId); try (var dbResult = dbStat.executeQuery()) { if (!dbResult.next()) { throw new SMException("Token not found"); } - return dbResult.getString(1); + return new SMTokens(dbResult.getString(1), dbResult.getString(2)); + } + } catch (SQLException e) { + throw new DBCException("Error reading token info in database", e); + } + } + + private RefreshTokenInfo findRefreshToken(String smAccessToken) throws DBException { + try (Connection dbCon = database.openConnection(); + PreparedStatement dbStat = dbCon.prepareStatement( + "SELECT REFRESH_TOKEN_ID,SESSION_ID,USER_ID,REFRESH_TOKEN_EXPIRATION_TIME FROM CB_AUTH_TOKEN WHERE TOKEN_ID=?" + ) + ) { + dbStat.setString(1, smAccessToken); + try (var dbResult = dbStat.executeQuery()) { + if (!dbResult.next()) { + throw new SMException("Refresh token not found"); + } + var refreshToken = dbResult.getString(1); + var sessionId = dbResult.getString(2); + var userId = dbResult.getString(3); + var expiredDate = dbResult.getTimestamp(4); + if (Timestamp.from(Instant.now()).after(expiredDate)) { + throw new SMRefreshTokenExpiredException("Refresh token expired"); + } + return new RefreshTokenInfo(refreshToken, sessionId, userId); } } catch (SQLException e) { throw new DBCException("Error reading token info in database", e); @@ -1173,12 +1232,12 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen AuthAttemptSessionInfo authAttemptSessionInfo = readAuthAttemptSessionInfo(authId); boolean isMainAuthSession = authAttemptSessionInfo.getSmSessionId() == null; - String token = null; + SMTokens smTokens = null; SMAuthPermissions permissions = null; if (!isMainAuthSession) { //this is an additional authorization and we should to return the original permissions and userId - token = findTokenBySmSession(authAttemptSessionInfo.getSmSessionId()); - permissions = getTokenPermissions(token); + smTokens = findTokenBySmSession(authAttemptSessionInfo.getSmSessionId()); + permissions = getTokenPermissions(smTokens.getSmAccessToken()); } String activeUserId = permissions == null ? null : permissions.getUserId(); @@ -1208,7 +1267,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen ); } - if (token == null && permissions == null) { + if (smTokens == null && permissions == null) { try (Connection dbCon = database.openConnection()) { try (JDBCTransaction txn = new JDBCTransaction(dbCon)) { String smSessionId; @@ -1223,7 +1282,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } else { smSessionId = authAttemptSessionInfo.getSmSessionId(); } - token = generateAuthToken(smSessionId, activeUserId, dbCon); + smTokens = generateNewSessionToken(smSessionId, activeUserId, dbCon); permissions = new SMAuthPermissions(activeUserId, smSessionId, getUserPermissions(activeUserId)); txn.commit(); } @@ -1235,7 +1294,14 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen } var authStatus = forceExpireAuthAfterSuccess ? SMAuthStatus.EXPIRED : SMAuthStatus.SUCCESS; updateAuthStatus(authId, authStatus, storedUserData, null, permissions.getSessionId()); - return SMAuthInfo.success(authId, token, permissions, authInfo.getAuthData()); + return SMAuthInfo.success( + authId, + smTokens.getSmAccessToken(), + //refresh token must be sent only once + isMainAuthSession ? smTokens.getSmRefreshToken() : null, + permissions, + authInfo.getAuthData() + ); } private AuthAttemptSessionInfo readAuthAttemptSessionInfo(@NotNull String authId) throws DBException { @@ -1316,28 +1382,40 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen return userId; } - protected String generateAuthToken( + protected SMTokens generateNewSessionToken( @NotNull String smSessionId, @Nullable String userId, @NotNull Connection dbCon ) throws SQLException, DBException { JDBCUtils.executeStatement(dbCon, "DELETE FROM CB_AUTH_TOKEN WHERE SESSION_ID=?", smSessionId); - try (PreparedStatement dbStat = dbCon.prepareStatement( - "INSERT INTO CB_AUTH_TOKEN(TOKEN_ID, SESSION_ID, USER_ID, EXPIRATION_TIME) " + - "VALUES(?,?,?,?)")) { + return generateNewSessionTokens(smSessionId, userId, dbCon); + } - String authToken = SecurityUtils.generatePassword(32); - dbStat.setString(1, authToken); + private SMTokens generateNewSessionTokens(@NotNull String smSessionId, + @Nullable String userId, + @NotNull Connection dbCon) throws SQLException { + try (PreparedStatement dbStat = dbCon.prepareStatement( + "INSERT INTO CB_AUTH_TOKEN(TOKEN_ID,SESSION_ID,USER_ID,EXPIRATION_TIME,REFRESH_TOKEN_ID,REFRESH_TOKEN_EXPIRATION_TIME) " + + "VALUES(?,?,?,?,?,?)")) { + + String smAccessToken = SecurityUtils.generatePassword(32); + dbStat.setString(1, smAccessToken); dbStat.setString(2, smSessionId); if (userId == null) { dbStat.setNull(3, Types.VARCHAR); } else { dbStat.setString(3, userId); } - var expirationTime = Timestamp.valueOf(LocalDateTime.now().plusHours(TOKEN_HOURS_ALIVE_TIME)); - dbStat.setTimestamp(4, expirationTime); + var accessTokenExpirationTime = Timestamp.valueOf(LocalDateTime.now().plusMinutes(ACCESS_TOKEN_TTL_IN_MINUTES)); + dbStat.setTimestamp(4, accessTokenExpirationTime); + + String smRefreshToken = SecurityUtils.generatePassword(32); + dbStat.setString(5, smRefreshToken); + var refreshTokenExpirationTime = Timestamp.valueOf(LocalDateTime.now().plusHours(REFRESH_TOKEN_TTL_IN_HOURS)); + dbStat.setTimestamp(6, refreshTokenExpirationTime); + dbStat.execute(); - return authToken; + return new SMTokens(smAccessToken, smRefreshToken); } } @@ -1356,7 +1434,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen userId = dbResult.getString(1); var expiredDate = dbResult.getTimestamp(2); if (application.isMultiNode() && Timestamp.from(Instant.now()).after(expiredDate)) { - throw new SMException("Token expired"); + throw new SMAccessTokenExpiredException("Token expired"); } sessionId = dbResult.getString(3); } diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java index 20217c60f5..6bd385c8b6 100644 --- a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/db/CBDatabase.java @@ -68,7 +68,7 @@ public class CBDatabase { public static final String SCHEMA_UPDATE_SQL_PATH = "db/cb_schema_update_"; private static final int LEGACY_SCHEMA_VERSION = 1; - private static final int CURRENT_SCHEMA_VERSION = 8; + private static final int CURRENT_SCHEMA_VERSION = 9; private static final String DEFAULT_DB_USER_NAME = "cb-data"; private static final String DEFAULT_DB_PWD_FILE = ".database-credentials.dat"; diff --git a/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/RefreshTokenInfo.java b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/RefreshTokenInfo.java new file mode 100644 index 0000000000..89d39430cd --- /dev/null +++ b/server/bundles/io.cloudbeaver.service.security/src/io/cloudbeaver/service/security/internal/RefreshTokenInfo.java @@ -0,0 +1,52 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2022 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.cloudbeaver.service.security.internal; + +import org.jkiss.code.NotNull; + +public class RefreshTokenInfo { + @NotNull + private final String refreshToken; + + @NotNull + private final String sessionId; + + @NotNull + private final String userId; + + public RefreshTokenInfo(@NotNull String refreshToken, @NotNull String sessionId, @NotNull String userId) { + this.refreshToken = refreshToken; + this.sessionId = sessionId; + this.userId = userId; + } + + @NotNull + public String getRefreshToken() { + return refreshToken; + } + + @NotNull + public String getSessionId() { + return sessionId; + } + + @NotNull + public String getUserId() { + return userId; + } +} diff --git a/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml b/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml index e5e59870a4..0016374b8b 100644 --- a/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml +++ b/server/features/io.cloudbeaver.ce.drivers.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml b/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml index 158e2b6e27..9d0aa29a64 100644 --- a/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml +++ b/server/features/io.cloudbeaver.ce.drivers.feature/pom.xml @@ -9,6 +9,6 @@ ../ io.cloudbeaver.ce.drivers.feature - 1.0.79-SNAPSHOT + 1.0.80-SNAPSHOT eclipse-feature diff --git a/server/features/io.cloudbeaver.product.ce.feature/feature.xml b/server/features/io.cloudbeaver.product.ce.feature/feature.xml index 94cf4d5ab5..fb588dfa1d 100644 --- a/server/features/io.cloudbeaver.product.ce.feature/feature.xml +++ b/server/features/io.cloudbeaver.product.ce.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/server/features/io.cloudbeaver.product.ce.feature/pom.xml b/server/features/io.cloudbeaver.product.ce.feature/pom.xml index f007f17138..78ccca0e67 100644 --- a/server/features/io.cloudbeaver.product.ce.feature/pom.xml +++ b/server/features/io.cloudbeaver.product.ce.feature/pom.xml @@ -10,7 +10,7 @@ ../ io.cloudbeaver.product.ce.feature - 22.1.5-SNAPSHOT + 22.2.0-SNAPSHOT eclipse-feature diff --git a/server/features/io.cloudbeaver.server.feature/feature.xml b/server/features/io.cloudbeaver.server.feature/feature.xml index a05955f56e..7a4032a6eb 100644 --- a/server/features/io.cloudbeaver.server.feature/feature.xml +++ b/server/features/io.cloudbeaver.server.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/server/features/io.cloudbeaver.server.feature/pom.xml b/server/features/io.cloudbeaver.server.feature/pom.xml index f7981eec85..a1fda267bc 100644 --- a/server/features/io.cloudbeaver.server.feature/pom.xml +++ b/server/features/io.cloudbeaver.server.feature/pom.xml @@ -10,6 +10,6 @@ ../ io.cloudbeaver.server.feature - 22.1.5-SNAPSHOT + 22.2.0-SNAPSHOT eclipse-feature diff --git a/server/features/io.cloudbeaver.ws.feature/feature.xml b/server/features/io.cloudbeaver.ws.feature/feature.xml index 79da427f63..5f472b85f8 100644 --- a/server/features/io.cloudbeaver.ws.feature/feature.xml +++ b/server/features/io.cloudbeaver.ws.feature/feature.xml @@ -2,7 +2,7 @@ diff --git a/server/features/io.cloudbeaver.ws.feature/pom.xml b/server/features/io.cloudbeaver.ws.feature/pom.xml index 74c286d66f..3432c0ab49 100644 --- a/server/features/io.cloudbeaver.ws.feature/pom.xml +++ b/server/features/io.cloudbeaver.ws.feature/pom.xml @@ -10,6 +10,6 @@ ../ io.cloudbeaver.ws.feature - 1.0.9-SNAPSHOT + 1.0.10-SNAPSHOT eclipse-feature diff --git a/server/pom.xml b/server/pom.xml index 6bdc31506d..47c25dd7d5 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -19,7 +19,7 @@ CloudBeaver CE - 22.1.5 + 22.2.0 diff --git a/server/product/web-server/CloudbeaverServer.product b/server/product/web-server/CloudbeaverServer.product index 4c0effb006..45412eb7b4 100644 --- a/server/product/web-server/CloudbeaverServer.product +++ b/server/product/web-server/CloudbeaverServer.product @@ -2,7 +2,7 @@ diff --git a/server/product/web-server/pom.xml b/server/product/web-server/pom.xml index 9a2649c358..c8acd31027 100644 --- a/server/product/web-server/pom.xml +++ b/server/product/web-server/pom.xml @@ -9,7 +9,7 @@ 1.0.0-SNAPSHOT ../../ - 22.1.5-SNAPSHOT + 22.2.0-SNAPSHOT web-server eclipse-repository Cloudbeaver Server Product diff --git a/webapp/packages/core-app/src/locales/en.ts b/webapp/packages/core-app/src/locales/en.ts index 6fd8778289..fd7f802d03 100644 --- a/webapp/packages/core-app/src/locales/en.ts +++ b/webapp/packages/core-app/src/locales/en.ts @@ -10,35 +10,6 @@ export default [ ['app_shared_settingsMenu_theme', 'Theme'], ['app_shared_settingsMenu_lang', 'Language'], ['app_topnavbar_connection_schema_manager_not_selected', '-- not selected --'], - ['app_navigationTree_openNodeTab', 'Open'], - ['app_navigationTree_search', 'Search elements...'], - ['app_navigationTree_limited', 'Elements are limited to {args.limit} items'], - ['app_navigationTree_action_link_with_editor', 'Link with editor'], - ['app_navigationTree_action_collapse_all', 'Collapse all'], - ['app_navigationTree_settings_filter_title', 'Filter'], - ['app_navigationTree_settings_filter_description', 'Show filtering field'], - ['app_navigationTree_settings_filter_all_title', 'Show collapsed'], - ['app_navigationTree_settings_filter_all_description', 'Shows filtered elements in collapsed folders'], - ['app_navigationTree_settings_state_title', 'Save tree state'], - ['app_navigationTree_settings_state_description', 'Reopen expanded nodes after page refresh'], - ['app_navigationTree_settings_folders_title', 'Folders'], - ['app_navigationTree_settings_folders_description', 'Open any node as tree root node'], - ['app_navigationTree_node_delete_confirmation', 'You\'re going to delete "{args.name}". Are you sure?'], - ['app_navigationTree_node_delete_error', 'Failed to delete "{args.name}'], - ['app_navigationTree_node_rename_error', 'Error occurred while renaming'], - ['app_navigationTree_node_empty', 'Empty'], - ['app_navigationTree_node_not_found', 'Node not found'], - ['app_navigationTree_connection_view', 'Connection view'], - ['app_navigationTree_connection_view_option_simple', 'Simple'], - ['app_navigationTree_connection_view_option_advanced', 'Advanced'], - ['app_navigationTree_connection_view_option_custom', 'Custom'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Show system objects'], - ['app_navigationTree_refresh', 'Refresh'], - ['app_navigationTree_refresh_error', 'Failed to refresh node'], - ['app_navigationTree_node_change_name_error', 'Error occurred while changing name'], - ['app_navigationTree_context_disconnect', 'Disconnect'], - ['app_navigationTree_connection_group_user', 'User Connections'], - ['app_navigationTree_connection_group_shared', 'Shared Connections'], ['app_shared_inlineEditor_dialog_title', 'Edit mode'], ['app_shared_inlineEditor_dialog_apply', 'Apply'], ['app_shared_inlineEditor_dialog_cancel', 'Cancel'], diff --git a/webapp/packages/core-app/src/locales/it.ts b/webapp/packages/core-app/src/locales/it.ts index baeaa52e81..57bda48d0d 100644 --- a/webapp/packages/core-app/src/locales/it.ts +++ b/webapp/packages/core-app/src/locales/it.ts @@ -10,34 +10,6 @@ export default [ ['app_shared_settingsMenu_theme', 'Tema'], ['app_shared_settingsMenu_lang', 'Lingua'], ['app_topnavbar_connection_schema_manager_not_selected', '-- non selezionato --'], - ['app_navigationTree_openNodeTab', 'Apri'], - ['app_navigationTree_search', 'Search elements...'], - ['app_navigationTree_limited', 'Elements are limited to {args.limit} items'], - ['app_navigationTree_action_link_with_editor', 'Link with editor'], - ['app_navigationTree_action_collapse_all', 'Collapse all'], - ['app_navigationTree_settings_filter_title', 'Filter'], - ['app_navigationTree_settings_filter_description', 'Show filtering field'], - ['app_navigationTree_settings_filter_all_title', 'Show collapsed'], - ['app_navigationTree_settings_filter_all_description', 'Shows filtered elements in collapsed folders'], - ['app_navigationTree_node_delete_confirmation', 'You\'re going to delete "{args.name}". Are you sure?'], - ['app_navigationTree_node_delete_error', 'Failed to delete "{args.name}'], - ['app_navigationTree_node_rename_error', 'Error occurred while renaming'], - ['app_navigationTree_settings_state_title', 'Save tree state'], - ['app_navigationTree_settings_state_description', 'Reopen expanded nodes after page refresh'], - ['app_navigationTree_settings_folders_title', 'Folders'], - ['app_navigationTree_settings_folders_description', 'Open any node as tree root node'], - ['app_navigationTree_node_empty', 'Empty'], - ['app_navigationTree_node_not_found', 'Node not found'], - ['app_navigationTree_connection_view', 'Vista di connessione'], - ['app_navigationTree_connection_view_option_simple', 'Semplice'], - ['app_navigationTree_connection_view_option_advanced', 'Avanzato'], - ['app_navigationTree_connection_view_option_custom', 'Manuale'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Mostra oggetti di sistema'], - ['app_navigationTree_refresh', 'Aggiorna'], - ['app_navigationTree_refresh_error', 'Failed to refresh node'], - ['app_navigationTree_context_disconnect', 'Scollega'], - ['app_navigationTree_connection_group_user', 'Connessioni Utente'], - ['app_navigationTree_connection_group_shared', 'Connessioni Condivise'], ['app_shared_inlineEditor_dialog_title', 'Modalità modifica'], ['app_shared_inlineEditor_dialog_apply', 'Applica'], ['app_shared_inlineEditor_dialog_cancel', 'Cancella'], diff --git a/webapp/packages/core-app/src/locales/ru.ts b/webapp/packages/core-app/src/locales/ru.ts index 6e89833e21..65641a84ee 100644 --- a/webapp/packages/core-app/src/locales/ru.ts +++ b/webapp/packages/core-app/src/locales/ru.ts @@ -13,38 +13,6 @@ export default [ 'app_shared_navigationTabsBar_placeholder', 'Нет открытых объектов для отображения. Дважды нажмите на элемент в дереве навигации, чтобы открыть его.', ], - ['app_navigationTree_openNodeTab', 'Открыть'], - ['app_navigationTree_search', 'Искать элементы...'], - ['app_navigationTree_limited', 'Отображено {args.limit} элементов'], - - ['app_navigationTree_action_link_with_editor', 'Синхронизовать с редактором'], - ['app_navigationTree_action_collapse_all', 'Свернуть все элементы'], - - ['app_navigationTree_settings_filter_title', 'Фильтр'], - ['app_navigationTree_settings_filter_description', 'Показывать фильтр'], - ['app_navigationTree_settings_filter_all_title', 'Фильтровать скрытые элементы'], - ['app_navigationTree_settings_filter_all_description', 'Показывает скрытые элементы при использовании фильтра'], - ['app_navigationTree_settings_state_title', 'Сохранять состояние дерева'], - ['app_navigationTree_settings_state_description', 'Восстанавливает открытые узлы после обновления страницы'], - ['app_navigationTree_settings_folders_title', 'Папки'], - ['app_navigationTree_settings_folders_description', 'Позволяет открыть любой узел как начальный'], - ['app_navigationTree_node_delete_confirmation', 'Вы собираетесь удалить "{args.name}". Вы уверены?'], - ['app_navigationTree_node_delete_error', 'Ошибка удаления "{args.name}'], - ['app_navigationTree_node_rename_error', 'Ошибка переименования ноды'], - - ['app_navigationTree_node_empty', 'Пусто'], - ['app_navigationTree_node_not_found', 'Элемент не найден'], - ['app_navigationTree_connection_view', 'Отображение'], - ['app_navigationTree_connection_view_option_simple', 'Упрощенное'], - ['app_navigationTree_connection_view_option_advanced', 'Продвинутое'], - ['app_navigationTree_connection_view_option_custom', 'Настраиваемое'], - ['app_navigationTree_connection_view_option_showSystemObjects', 'Показывать системные объекты'], - ['app_navigationTree_refresh', 'Обновить'], - ['app_navigationTree_refresh_error', 'Не удалось обновить узел'], - ['app_navigationTree_node_change_name_error', 'Не удалось изменить название'], - ['app_navigationTree_context_disconnect', 'Отключить'], - ['app_navigationTree_connection_group_user', 'Пользовательские подключения'], - ['app_navigationTree_connection_group_shared', 'Общие подключения'], ['app_shared_inlineEditor_dialog_title', 'Редактирование'], ['app_shared_inlineEditor_dialog_apply', 'Применить'], ['app_shared_inlineEditor_dialog_cancel', 'Отменить'], diff --git a/webapp/packages/core-app/src/locales/zh.ts b/webapp/packages/core-app/src/locales/zh.ts index 122d76ca25..f3abaf8b5d 100644 --- a/webapp/packages/core-app/src/locales/zh.ts +++ b/webapp/packages/core-app/src/locales/zh.ts @@ -10,35 +10,6 @@ export default [ ['app_shared_settingsMenu_theme', '主题'], ['app_shared_settingsMenu_lang', '语言'], ['app_topnavbar_connection_schema_manager_not_selected', '-- 为选择 --'], - ['app_navigationTree_search', 'Search elements...'], - ['app_navigationTree_limited', 'Elements are limited to {args.limit} items'], - ['app_navigationTree_action_link_with_editor', 'Link with editor'], - ['app_navigationTree_action_collapse_all', 'Collapse all'], - ['app_navigationTree_settings_filter_title', 'Filter'], - ['app_navigationTree_settings_filter_description', 'Show filtering field'], - ['app_navigationTree_settings_filter_all_title', 'Show collapsed'], - ['app_navigationTree_settings_filter_all_description', 'Shows filtered elements in collapsed folders'], - ['app_navigationTree_settings_state_title', 'Save tree state'], - ['app_navigationTree_settings_state_description', 'Reopen expanded nodes after page refresh'], - ['app_navigationTree_settings_folders_title', 'Folders'], - ['app_navigationTree_settings_folders_description', 'Open any node as tree root node'], - ['app_navigationTree_node_delete_confirmation', 'You\'re going to delete "{args.name}". Are you sure?'], - ['app_navigationTree_node_delete_error', 'Failed to delete "{args.name}'], - ['app_navigationTree_node_rename_error', 'Error occurred while renaming'], - ['app_navigationTree_node_empty', 'Empty'], - ['app_navigationTree_openNodeTab', '打开'], - ['app_navigationTree_connection_view', '连接视图'], - ['app_navigationTree_node_not_found', 'Node not found'], - ['app_navigationTree_connection_view_option_simple', '简单'], - ['app_navigationTree_connection_view_option_advanced', '完善'], - ['app_navigationTree_connection_view_option_custom', '自定义'], - ['app_navigationTree_connection_view_option_showSystemObjects', '展示系统对象'], - ['app_navigationTree_refresh', '刷新'], - ['app_navigationTree_refresh_error', 'Failed to refresh node'], - ['app_navigationTree_node_change_name_error', '更改名称时发生错误'], - ['app_navigationTree_context_disconnect', '断开连接'], - ['app_navigationTree_connection_group_user', '用户连接'], - ['app_navigationTree_connection_group_shared', '共享连接'], ['app_shared_inlineEditor_dialog_title', '编辑模式'], ['app_shared_inlineEditor_dialog_apply', '应用'], ['app_shared_inlineEditor_dialog_cancel', '取消'], diff --git a/webapp/packages/core-authentication/src/UserInfoResource.ts b/webapp/packages/core-authentication/src/UserInfoResource.ts index 961e659f95..447e2d7ee8 100644 --- a/webapp/packages/core-authentication/src/UserInfoResource.ts +++ b/webapp/packages/core-authentication/src/UserInfoResource.ts @@ -119,7 +119,7 @@ UserInfoIncludes return authInfo as AuthInfo; } - finishFederatedAuthentication(authId: string, link?: boolean): ITask { + finishFederatedAuthentication(authId: string, linkUser?: boolean): ITask { let activeTask: ITask | undefined; return new AutoRunningTask(() => this.performUpdate( @@ -139,7 +139,7 @@ UserInfoIncludes async () => { const { authInfo } = await this.graphQLService.sdk.getAuthStatus({ authId, - linkUser: link, + linkUser, customIncludeOriginDetails: true, }); return authInfo as AuthInfo; diff --git a/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs b/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs index 95176d4a64..bcebfe5cef 100644 --- a/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs +++ b/webapp/packages/core-blocks/src/HTMLTemplates/head.html.ejs @@ -7,8 +7,6 @@ -