Skip to content

Commit

Permalink
CB-4436 update session only in touchSession (#2377)
Browse files Browse the repository at this point in the history
* CB-4436 update session only in touchSession

* CB-4346 adds session touch for user actions

* CB-4346 adds core-activity package

* CB-4346 fix: mobx version core-activity package

* CB-4346 ClientActivityService cleanup

* CB-4346 ClientActivityService cleanup [2]

* CB-4346 fix: client activity function contexts bind

* CB-4346 useClientActivity cleanup

* CB-4346 removed unneeded deps

* CB-4346 session warning dialog props renaming

* CB-4364 adds client activity service setsActivity method

* CB-4346 activity timers refactor

* CB-4346 adds min time for session expire setting

* CB-4346 adds update client activity each 300ms

* CB-4346 touchSession logic moved to SessionExpiredService

* СB-4346 session expire service uses session resource to touchSession

* CB-4346 code cleanup

* CB-4346 removed unused activity package from plugin session expiration

* CB-4346 SessionExpireService - removed cycle dependency

* CB-4346 code cleanup

* CB-4346 update session state if it is invalid

* CB-4346 removed arrow function from useClientActivity

* Revert "CB-4346 SessionExpireService - removed cycle dependency"

This reverts commit adba2d5.

* CB-4346 touchSession logic moved from SessionExpiredService to SessionResource because of cycle dependency

* CB-4346 chore: core-activity -> core-client-activity renaming

* CB-4346 chore: vars renaming

* CB-4346 refactor: removed force from sessionResource.touchSession()

* CB-4346 adds SessionTouchService

* CB-4346 chore: SESSION_EXPIRE_MIN_TIME const new name

* CB-4346 sessionTouchService license

* CB-4346 uses SessionTouchService as Dependency

* CB-4346 pr fixes

* CB-4346 adds core-localization to plugin-session-expiration

* CB-4346 adds core coreClientActivityManifest to unit tests

* CB-4346 updates ts references

* CB-4436 new update session gql api

* CB-4346 adds updateSession API call

* CB-4346 code cleanup sessionResource

* CB-4346 do not send state event for not authorized session

* CB-4346 chore: update session info with event

* CB-4346 adds update activity on touch (tablets, phones support)

* CB-4346 add debug log

* CB-4346 force update session on create

---------

Co-authored-by: s.teleshev <[email protected]>
Co-authored-by: Aleksei Potsetsuev <[email protected]>
Co-authored-by: Evgenia Bezborodova <[email protected]>
  • Loading branch information
4 people authored Feb 23, 2024
1 parent 3898729 commit c0c4e18
Show file tree
Hide file tree
Showing 82 changed files with 489 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ public synchronized void updateInfo(
HttpServletRequest request,
HttpServletResponse response
) throws DBWebException {
log.debug("Update session lifetime " + getSessionId() + " for user " + getUserId());
touchSession();
HttpSession httpSession = request.getSession();
this.lastRemoteAddr = request.getRemoteAddr();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,9 @@ extend type Mutation {
closeSession: Boolean

# Refreshes session on server and returns its state
touchSession: Boolean
touchSession: Boolean @deprecated(reason: "use updateSession instead")
# Refreshes session on server and returns session state
updateSession: SessionInfo! @since(version: "24.0.0")

# Refresh session connection list
refreshSessionConnections: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,14 @@ WebSession openSession(
@WebAction(authRequired = false)
boolean closeSession(HttpServletRequest request) throws DBWebException;

@Deprecated
@WebAction(authRequired = false)
boolean touchSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse servletResponse) throws DBWebException;

@WebAction(authRequired = false)
WebSession updateSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response)
throws DBWebException;

@WebAction(authRequired = false)
boolean refreshSessionConnections(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public void bindWiring(DBWBindingContext model) throws DBWebException {
.dataFetcher("closeSession", env -> getService(env).closeSession(GraphQLEndpoint.getServletRequest(env)))
.dataFetcher("touchSession", env -> getService(env).touchSession(
GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env)))
.dataFetcher("updateSession", env -> getService(env).updateSession(
GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env)))
.dataFetcher("refreshSessionConnections", env -> getService(env).refreshSessionConnections(
GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env)))
.dataFetcher("changeSessionLanguage", env -> getService(env).changeSessionLanguage(getWebSession(env), env.getArgument("locale")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.cloudbeaver.server.CBPlatform;
import io.cloudbeaver.service.core.DBWServiceCore;
import io.cloudbeaver.service.security.SMUtils;
import io.cloudbeaver.service.session.WebSessionManager;
import io.cloudbeaver.utils.WebConnectionFolderUtils;
import io.cloudbeaver.utils.WebDataSourceUtils;
import io.cloudbeaver.utils.WebEventUtils;
Expand Down Expand Up @@ -285,6 +286,14 @@ public boolean touchSession(@NotNull HttpServletRequest request, @NotNull HttpSe
return CBPlatform.getInstance().getSessionManager().touchSession(request, response);
}

@Override
public WebSession updateSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response)
throws DBWebException {
WebSessionManager sessionManager = CBPlatform.getInstance().getSessionManager();
sessionManager.touchSession(request, response);
return sessionManager.getWebSession(request, response, true);
}

@Override
public boolean refreshSessionConnections(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException {
WebSession session = CBPlatform.getInstance().getSessionManager().getWebSession(request, response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,11 @@ public WebSession getWebSession(@NotNull HttpServletRequest request,
}

@NotNull
public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, boolean errorOnNoFound) throws DBWebException {
return getWebSession(request, response, true, errorOnNoFound);
}

@NotNull
public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, boolean updateInfo, boolean errorOnNoFound) throws DBWebException {
public WebSession getWebSession(
@NotNull HttpServletRequest request,
@NotNull HttpServletResponse response,
boolean errorOnNoFound
) throws DBWebException {
HttpSession httpSession = request.getSession(true);
String sessionId = httpSession.getId();
WebSession webSession;
Expand Down Expand Up @@ -132,20 +131,14 @@ public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull Ht
log.debug((restored ? "Restored " : "New ") + "web session '" + webSession.getSessionId() + "'");

webSession.setCacheExpired(!httpSession.isNew());
webSession.updateInfo(request, response);

sessionMap.put(sessionId, webSession);
} else {
if (!(baseWebSession instanceof WebSession)) {
throw new DBWebException("Unexpected session type: " + baseWebSession.getClass().getName());
}
webSession = (WebSession) baseWebSession;
if (updateInfo) {
// Update only once per request
if (!CommonUtils.toBoolean(request.getAttribute("sessionUpdated"))) {
webSession.updateInfo(request, response);
request.setAttribute("sessionUpdated", true);
}
}
}
}

Expand Down Expand Up @@ -328,16 +321,21 @@ public WebHeadlessSession getHeadlessSession(HttpServletRequest request, boolean
*/
public void sendSessionsStates() {
synchronized (sessionMap) {
for (var session : sessionMap.values()) {
if (session instanceof WebHeadlessSession) {
continue;
}
try {
session.addSessionEvent(new WSSessionStateEvent(session.getRemainingTime(), session.isValid()));
} catch (Exception e) {
log.error("Failed to refresh session state: " + session.getSessionId(), e);
}
}
sessionMap.values()
.parallelStream()
.filter(session -> {
if (session instanceof WebSession webSession) {
return webSession.isAuthorizedInSecurityManager();
}
return false;
})
.forEach(session -> {
try {
session.addSessionEvent(new WSSessionStateEvent(session.getRemainingTime(), session.isValid()));
} catch (Exception e) {
log.error("Failed to refresh session state: " + session.getSessionId(), e);
}
});
}
}

Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-administration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-events": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import '@testing-library/jest-dom';

import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreEventsManifest } from '@cloudbeaver/core-events';
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
import { corePluginManifest } from '@cloudbeaver/core-plugin';
Expand Down Expand Up @@ -37,6 +38,7 @@ const app = createApp(
// coreRoutingManifest,
// coreThemingManifest,
coreLocalizationManifest,
coreClientActivityManifest,
);

const server = mockGraphQL(...mockAppInit(endpoint));
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-administration/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-data-context/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"dependencies": {
"@cloudbeaver/core-blocks": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-di": "~0.1.0",
"@cloudbeaver/core-executor": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/core-app/src/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useAppVersion } from '@cloudbeaver/core-version';

import style from './Body.m.css';
import { useAppHeight } from './useAppHeight';
import { useClientActivity } from './useClientActivity';

export const Body = observer(function Body() {
// const serverConfigLoader = useResource(Body, ServerConfigResource, undefined);
Expand All @@ -44,6 +45,7 @@ export const Body = observer(function Body() {
});

useAppHeight();
useClientActivity();

return (
<DNDProvider>
Expand Down
46 changes: 46 additions & 0 deletions webapp/packages/core-app/src/useClientActivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { useEffect } from 'react';

import { ClientActivityService } from '@cloudbeaver/core-client-activity';
import { useService } from '@cloudbeaver/core-di';
import { throttle } from '@cloudbeaver/core-utils';

const UPDATE_THROTTLE = 300;

export function useClientActivity() {
const clientActivityService = useService(ClientActivityService);

const updateActivity = throttle(function updateActivity() {
clientActivityService.updateActivity();
}, UPDATE_THROTTLE);

function subscribeEvents() {
document.addEventListener('mousemove', updateActivity);
document.addEventListener('click', updateActivity);
document.addEventListener('keydown', updateActivity);
document.addEventListener('scroll', updateActivity);
document.addEventListener('touchstart', updateActivity);
}

function unsubscribeEvents() {
document.removeEventListener('mousemove', updateActivity);
document.removeEventListener('click', updateActivity);
document.removeEventListener('keydown', updateActivity);
document.removeEventListener('scroll', updateActivity);
document.removeEventListener('touchstart', updateActivity);
}

useEffect(() => {
subscribeEvents();

return () => {
unsubscribeEvents();
};
}, []);
}
3 changes: 3 additions & 0 deletions webapp/packages/core-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
{
"path": "../core-blocks/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-di/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-authentication/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-events": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import '@testing-library/jest-dom';

import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreEventsManifest } from '@cloudbeaver/core-events';
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
import { corePluginManifest } from '@cloudbeaver/core-plugin';
Expand Down Expand Up @@ -40,6 +41,7 @@ const app = createApp(
coreRoutingManifest,
coreThemingManifest,
coreLocalizationManifest,
coreClientActivityManifest,
);

const server = mockGraphQL(...mockAppInit(endpoint), ...mockAuthentication(endpoint));
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-authentication/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-data-context/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-blocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-events": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/core-blocks/src/ErrorMessage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import '@testing-library/jest-dom';
import { screen } from '@testing-library/react';

import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreEventsManifest } from '@cloudbeaver/core-events';
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
import { corePluginManifest } from '@cloudbeaver/core-plugin';
Expand All @@ -35,6 +36,7 @@ const app = createApp(
coreBrowserManifest,
coreThemingManifest,
coreLocalizationManifest,
coreClientActivityManifest,
);

mockGraphQL(...mockAppInit(endpoint));
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-blocks/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-di/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-bootstrap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-browser-cookies": "~0.1.0",
"@cloudbeaver/core-browser-settings": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-connections": "~0.1.0",
"@cloudbeaver/core-di": "~0.1.0",
"@cloudbeaver/core-dialogs": "~0.1.0",
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/core-bootstrap/src/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { coreBlocksManifest } from '@cloudbeaver/core-blocks';
import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreBrowserCookiesManifest } from '@cloudbeaver/core-browser-cookies';
import { coreBrowserSettingsManifest } from '@cloudbeaver/core-browser-settings';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreConnectionsManifest } from '@cloudbeaver/core-connections';
import { coreDIManifest, PluginManifest } from '@cloudbeaver/core-di';
import { coreDialogsManifest } from '@cloudbeaver/core-dialogs';
Expand Down Expand Up @@ -74,5 +75,6 @@ export const coreManifests: PluginManifest[] = [
coreDialogsManifest,
resourceManagerManifest,
coreAppManifest,
coreClientActivityManifest,
coreNavigationTree,
];
3 changes: 3 additions & 0 deletions webapp/packages/core-bootstrap/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-connections/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-browser-settings/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
"@cloudbeaver/core-product": "~0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import '@testing-library/jest-dom';

import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
import { corePluginManifest } from '@cloudbeaver/core-plugin';
import { coreProductManifest } from '@cloudbeaver/core-product';
Expand All @@ -33,6 +34,7 @@ const app = createApp(
coreSDKManifest,
coreSettingsManifest,
coreLocalizationManifest,
coreClientActivityManifest,
);

const server = mockGraphQL(...mockAppInit(endpoint));
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-browser-settings/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-di/tsconfig.json"
},
Expand Down
Loading

0 comments on commit c0c4e18

Please sign in to comment.