[ADD] web_session_auto_close

This commit adds the web_session_auto_close module which purpose is
to is to automatically close the session when the last odoo tab is
closed or when the computer gets in idle mode.

The `timeout` occurs 15 seconds after the tab has been closed or
the computer got idle.
This commit is contained in:
Laurent Stukkens
2023-08-17 09:32:11 +02:00
parent ab916ebf6d
commit 85b83d199d
17 changed files with 738 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
odoo.define("web_session_auto_close.BusService", function(require) {
"use strict";
const BusService = require("bus.BusService");
const LocalStorageServiceMixin = require("web_session_auto_close.LocalStorageServiceMixin");
return BusService.include(
Object.assign(LocalStorageServiceMixin, {
/**
* @override
* @private
*/
_heartbeat() {
this._updateLocalStorageLastPresence();
this._super.apply(this, arguments);
},
/**
* Return whether the current session is valid and does not require a logout.
* @returns {Boolean}
*/
isSessionStillValid() {
let sessionLastPresenceTime = this._getLocalStorageLastPresence() || 0;
try {
sessionLastPresenceTime = parseInt(sessionLastPresenceTime);
} catch (e) {
this._clearLocalStorageLastPresence();
sessionLastPresenceTime = 0;
}
const timeSinceLastPageRefresh =
new Date().getTime() - sessionLastPresenceTime;
return (
sessionLastPresenceTime === 0 ||
timeSinceLastPageRefresh < this.HEARTBEAT_KILL_OLD_PERIOD
);
},
})
);
});

View File

@@ -0,0 +1,46 @@
odoo.define("web_session_auto_close.LocalStorageServiceMixin", function() {
"use strict";
return {
/**
* Get the local storage key to use to manage the last presence time.
* @returns {String} the key of the local storage.
* @private
*/
_getLocalStorageLastPresenceKey() {
const window_origin = location.protocol + "//" + location.host;
// Replace ':', '/' & '//' by '_'
const sanitized_origin = window_origin.replace(/:\/{0,2}/g, "_");
return `web_session_auto_close.${sanitized_origin}.lastPresenceTime`;
},
/**
* Update the last presence time in the local storage.
* @private
*/
_updateLocalStorageLastPresence() {
const now = new Date().getTime();
localStorage.setItem(
this._getLocalStorageLastPresenceKey(),
now.toString()
);
},
/**
* Get the last presence time from the local storage.
* @returns {String} the last presence time stored in the local storage.
* @private
*/
_getLocalStorageLastPresence() {
return localStorage.getItem(this._getLocalStorageLastPresenceKey());
},
/**
* Clear the last presence key in the local storage.
* @private
*/
_clearLocalStorageLastPresence() {
localStorage.removeItem(this._getLocalStorageLastPresenceKey());
},
};
});

View File

@@ -0,0 +1,21 @@
odoo.define("web_session_auto_close.Session", function(require) {
"use strict";
const LocalStorageServiceMixin = require("web_session_auto_close.LocalStorageServiceMixin");
const WebSession = require("web.Session");
return WebSession.include(
Object.assign(LocalStorageServiceMixin, {
/**
* @override
*/
session_init() {
const result = this._super.apply(this, arguments);
if (!this.session_is_valid()) {
this._clearLocalStorageLastPresence();
}
return result;
},
})
);
});

View File

@@ -0,0 +1,24 @@
odoo.define("web_session_auto_close.WebClient", function(require) {
"use strict";
const WebClient = require("web.WebClient");
return WebClient.include({
dependencies: ["bus_service", WebClient.prototype.dependencies],
/**
* @override
*/
start: function() {
const isSessionStillValid = this.call("bus_service", "isSessionStillValid");
if (!isSessionStillValid) {
window.location = "/web/session/logout";
return;
}
const result = this._super.apply(this, arguments);
// We need to ensure that the polling has started as this module relies on that process.
this.call("bus_service", "startPolling");
return result;
},
});
});