asab_webui_shell 26.1.2 → 26.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/containers/Application.js +4 -21
- package/dist/containers/Sidebar/SidebarItem.js +1 -1
- package/dist/index.js +8 -1
- package/dist/modules/attentionrequired/index.js +21 -0
- package/dist/modules/attentionrequired/index.jsx +17 -0
- package/dist/modules/attentionrequired/reducer.jsx +20 -0
- package/dist/{services/AttentionRequiredService.js → modules/attentionrequired/service.js} +2 -1
- package/dist/modules/attentionrequired/service.jsx +141 -0
- package/dist/modules/auth/index.js +91 -109
- package/dist/modules/tenant/service.js +1 -1
- package/package.json +1 -1
- /package/dist/{containers/AttentionRequired → modules/attentionrequired}/reducer.js +0 -0
|
@@ -25,9 +25,7 @@ var _reducer4 = _interopRequireDefault(require("./Navigation/reducer"));
|
|
|
25
25
|
var _reducer5 = _interopRequireDefault(require("./Router/reducer"));
|
|
26
26
|
var _reducer6 = _interopRequireDefault(require("./FullscreenMode/reducer"));
|
|
27
27
|
var _reducer7 = _interopRequireDefault(require("./AdvancedMode/reducer"));
|
|
28
|
-
var _reducer8 = _interopRequireDefault(require("./AttentionRequired/reducer"));
|
|
29
28
|
var _ReduxService = _interopRequireDefault(require("../services/ReduxService"));
|
|
30
|
-
var _AttentionRequiredService = _interopRequireDefault(require("../services/AttentionRequiredService"));
|
|
31
29
|
var _ConfigService = _interopRequireDefault(require("../config/ConfigService"));
|
|
32
30
|
var _HeaderService = _interopRequireDefault(require("../services/HeaderService"));
|
|
33
31
|
var _ThemeService = _interopRequireDefault(require("../theme/ThemeService"));
|
|
@@ -82,21 +80,8 @@ class Application extends _react.Component {
|
|
|
82
80
|
constructor(props) {
|
|
83
81
|
super(props);
|
|
84
82
|
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
state: null,
|
|
88
|
-
dispatch: null
|
|
89
|
-
}; // Create the store object (fields stays writable so the provider can update them)
|
|
90
|
-
Object.seal(appStore); // Lock the shape, so no adding/removing properties (but existing fields remain writable)
|
|
91
|
-
Object.defineProperty(this, 'AppStore', {
|
|
92
|
-
value: appStore,
|
|
93
|
-
writable: false,
|
|
94
|
-
// Can't reassign this.AppStore
|
|
95
|
-
configurable: false,
|
|
96
|
-
// Can't redefine/delete the property
|
|
97
|
-
enumerable: true // Makes it show up in Object.keys/console
|
|
98
|
-
}); // Define a read-only, non-configurable property on the instance
|
|
99
|
-
|
|
83
|
+
// Create App store with global AppStore variables
|
|
84
|
+
this.AppStore = (0, _asab_webui_components.createAppStore)();
|
|
100
85
|
this.Modules = [];
|
|
101
86
|
this.Services = {};
|
|
102
87
|
this.ReduxService = new _ReduxService.default(this, "ReduxService");
|
|
@@ -104,7 +89,6 @@ class Application extends _react.Component {
|
|
|
104
89
|
this.Config = this.ConfigService.Config;
|
|
105
90
|
|
|
106
91
|
// Register reducers which are not part of any app service
|
|
107
|
-
this.ReduxService.addReducer("attentionrequired", _reducer8.default);
|
|
108
92
|
this.ReduxService.addReducer("alerts", _reducer.default);
|
|
109
93
|
this.ReduxService.addReducer("advmode", _reducer7.default);
|
|
110
94
|
this.ReduxService.addReducer("fullscreenmode", _reducer6.default);
|
|
@@ -117,7 +101,6 @@ class Application extends _react.Component {
|
|
|
117
101
|
this.SplashscreenRequestors = new Set(); // If not empty, the splash screen will be rendered
|
|
118
102
|
this.AxiosInterceptors = new Set();
|
|
119
103
|
this.WebSocketInterceptors = new Set();
|
|
120
|
-
this.AttentionRequiredService = new _AttentionRequiredService.default(this, "AttentionRequired");
|
|
121
104
|
this.HeaderService = new _HeaderService.default(this, "HeaderService");
|
|
122
105
|
this.ThemeService = new _ThemeService.default(this, "ThemeService");
|
|
123
106
|
this.BrandingService = new _BrandingService.default(this, "BrandingService");
|
|
@@ -599,7 +582,7 @@ class Application extends _react.Component {
|
|
|
599
582
|
var _this$AppStore$dispat3, _this$AppStore3;
|
|
600
583
|
if (enabled === 0) {
|
|
601
584
|
var _state$advmode;
|
|
602
|
-
var state = this.AppStore.
|
|
585
|
+
var state = this.AppStore.getState();
|
|
603
586
|
enabled = !(state !== null && state !== void 0 && (_state$advmode = state.advmode) !== null && _state$advmode !== void 0 && _state$advmode.enabled);
|
|
604
587
|
}
|
|
605
588
|
(_this$AppStore$dispat3 = (_this$AppStore3 = this.AppStore).dispatch) === null || _this$AppStore$dispat3 === void 0 || _this$AppStore$dispat3.call(_this$AppStore3, {
|
|
@@ -619,7 +602,7 @@ class Application extends _react.Component {
|
|
|
619
602
|
*/
|
|
620
603
|
setFullScreenMode(status) {
|
|
621
604
|
var _state$fullscreenmode, _this$AppStore$dispat4, _this$AppStore4;
|
|
622
|
-
var state = this.AppStore.
|
|
605
|
+
var state = this.AppStore.getState();
|
|
623
606
|
if (status === 'on' && (state === null || state === void 0 || (_state$fullscreenmode = state.fullscreenmode) === null || _state$fullscreenmode === void 0 ? void 0 : _state$fullscreenmode.status) === 'on') {
|
|
624
607
|
status = 'off';
|
|
625
608
|
}
|
|
@@ -38,7 +38,7 @@ var SidebarItem = _ref => {
|
|
|
38
38
|
var [isActive, setActive] = (0, _react.useState)(false);
|
|
39
39
|
var lowercasedItemName = item === null || item === void 0 || (_item$name = item.name) === null || _item$name === void 0 ? void 0 : _item$name.toLowerCase();
|
|
40
40
|
// Attention requred flag
|
|
41
|
-
var itemBeacon = beacon ? beacon["beacon.".concat(lowercasedItemName)] : attentionRequired["beacon.".concat(lowercasedItemName)];
|
|
41
|
+
var itemBeacon = beacon ? beacon["beacon.".concat(lowercasedItemName)] : attentionRequired === null || attentionRequired === void 0 ? void 0 : attentionRequired["beacon.".concat(lowercasedItemName)];
|
|
42
42
|
(0, _react.useEffect)(() => {
|
|
43
43
|
// TODO: refactor the handling of active and open states, since it does not behave as expected in some cases
|
|
44
44
|
if (isOpen && !isActive) {
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,12 @@ Object.defineProperty(exports, "Application", {
|
|
|
16
16
|
return _Application.default;
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
|
+
Object.defineProperty(exports, "AttentionRequiredModule", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function get() {
|
|
22
|
+
return _index2.default;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
19
25
|
Object.defineProperty(exports, "AuthModule", {
|
|
20
26
|
enumerable: true,
|
|
21
27
|
get: function get() {
|
|
@@ -46,4 +52,5 @@ var _BrandImage = require("./components/branding/BrandImage");
|
|
|
46
52
|
var _i18n = _interopRequireDefault(require("./modules/i18n"));
|
|
47
53
|
var _tenant = _interopRequireDefault(require("./modules/tenant"));
|
|
48
54
|
var _auth = _interopRequireDefault(require("./modules/auth"));
|
|
49
|
-
var _about = _interopRequireDefault(require("./modules/about"));
|
|
55
|
+
var _about = _interopRequireDefault(require("./modules/about"));
|
|
56
|
+
var _index2 = _interopRequireDefault(require("./modules/attentionrequired/index.js"));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _asab_webui_components = require("asab_webui_components");
|
|
10
|
+
var _service = _interopRequireDefault(require("./service.js"));
|
|
11
|
+
var _reducer = _interopRequireDefault(require("./reducer.js"));
|
|
12
|
+
class AttentionRequiredModule extends _asab_webui_components.Module {
|
|
13
|
+
constructor(app) {
|
|
14
|
+
var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "AttentionRequiredModule";
|
|
15
|
+
super(app, name);
|
|
16
|
+
this.App = app;
|
|
17
|
+
this.AttentionRequiredService = new _service.default(app, "AttentionRequiredService");
|
|
18
|
+
this.App.ReduxService.addReducer("attentionrequired", _reducer.default);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.default = AttentionRequiredModule;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Module } from 'asab_webui_components';
|
|
3
|
+
import AttentionRequiredService from './service.jsx';
|
|
4
|
+
import reducer from './reducer.jsx';
|
|
5
|
+
|
|
6
|
+
export default class AttentionRequiredModule extends Module {
|
|
7
|
+
|
|
8
|
+
constructor(app, name = "AttentionRequiredModule") {
|
|
9
|
+
super(app, name);
|
|
10
|
+
this.App = app;
|
|
11
|
+
|
|
12
|
+
this.AttentionRequiredService = new AttentionRequiredService(app, "AttentionRequiredService");
|
|
13
|
+
|
|
14
|
+
this.App.ReduxService.addReducer("attentionrequired", reducer);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { SET_ATTENTION_REQUIRED_BEACON } from "../../actions";
|
|
2
|
+
|
|
3
|
+
const initialState = {
|
|
4
|
+
beacon: {},
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Reducer for attention required, returning beacon
|
|
8
|
+
export default function attentionRequiredReducer(state = initialState, action) {
|
|
9
|
+
switch (action.type) {
|
|
10
|
+
case SET_ATTENTION_REQUIRED_BEACON: {
|
|
11
|
+
return {
|
|
12
|
+
...state,
|
|
13
|
+
beacon: action.beacon
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
default:
|
|
18
|
+
return state;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _asab_webui_components = require("asab_webui_components");
|
|
8
|
-
var _actions = require("
|
|
8
|
+
var _actions = require("../../actions");
|
|
9
9
|
// Service handling attention required
|
|
10
10
|
class AttentionRequiredService extends _asab_webui_components.Service {
|
|
11
11
|
constructor(app) {
|
|
@@ -101,6 +101,7 @@ class AttentionRequiredService extends _asab_webui_components.Service {
|
|
|
101
101
|
distributeData(data) {
|
|
102
102
|
var _this$App2, _this$App2$dispatch;
|
|
103
103
|
var transformedData = this.transformData(data);
|
|
104
|
+
// TODO: use a pubsub instead of the appstore dispatch
|
|
104
105
|
(_this$App2 = this.App) === null || _this$App2 === void 0 || (_this$App2 = _this$App2.AppStore) === null || _this$App2 === void 0 || (_this$App2$dispatch = _this$App2.dispatch) === null || _this$App2$dispatch === void 0 || _this$App2$dispatch.call(_this$App2, {
|
|
105
106
|
type: _actions.SET_ATTENTION_REQUIRED_BEACON,
|
|
106
107
|
beacon: transformedData
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Service } from 'asab_webui_components';
|
|
2
|
+
import { SET_ATTENTION_REQUIRED_BEACON } from '../../actions';
|
|
3
|
+
|
|
4
|
+
// Service handling attention required
|
|
5
|
+
export default class AttentionRequiredService extends Service {
|
|
6
|
+
|
|
7
|
+
constructor(app, serviceName="AttentionRequiredService"){
|
|
8
|
+
super(app, serviceName);
|
|
9
|
+
this.beaconWebSocket = null; // beacon websocket variable
|
|
10
|
+
this.reconnectTimeout = null; // timeout variable
|
|
11
|
+
this.reconnectInterval = 5000; // initial reconnection interval (5 seconds)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Start beacon websocket connection on initialization
|
|
15
|
+
initialize() {
|
|
16
|
+
this.connectBeaconWebSocket();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Method for connection to beacon websocket
|
|
20
|
+
connectBeaconWebSocket() {
|
|
21
|
+
// Retrieve current tenant
|
|
22
|
+
const currentTenant = this.App?.Services?.TenantService?.getCurrentTenant();
|
|
23
|
+
// Gracefully reconnect if tenant was not found
|
|
24
|
+
if (!currentTenant) {
|
|
25
|
+
console.error("Beacon WebSocket error: Tenant was not found!");
|
|
26
|
+
this.reconnectBeaconWebSocket();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const BeaconServiceClient = this.App.createWebSocket('asab-remote-control', `/beacon/${currentTenant}/ws`);
|
|
31
|
+
this.beaconWebSocket = BeaconServiceClient;
|
|
32
|
+
|
|
33
|
+
this.beaconWebSocket.onopen = () => {
|
|
34
|
+
// TODO: may be removed
|
|
35
|
+
console.log('Beacon WebSocket connection established.');
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
this.beaconWebSocket.onmessage = (message) => {
|
|
39
|
+
try {
|
|
40
|
+
const data = JSON.parse(message.data);
|
|
41
|
+
// TODO: implement some type based recognition
|
|
42
|
+
this.distributeData(data);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
console.error("Error parsing Beacon WebSocket message data:", e);
|
|
45
|
+
this.distributeData({});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
this.beaconWebSocket.onerror = (error) => {
|
|
50
|
+
console.error("Beacon WebSocket error:", error);
|
|
51
|
+
console.error("Beacon WebSocket is attempting to reconnect...");
|
|
52
|
+
this.distributeData({});
|
|
53
|
+
this.reconnectBeaconWebSocket();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
this.beaconWebSocket.onclose = () => {
|
|
57
|
+
/*
|
|
58
|
+
WebSocket connection is closed by the browser automatically when user
|
|
59
|
+
leaves the application (not the screen).
|
|
60
|
+
*/
|
|
61
|
+
if (this.beaconWebSocket) {
|
|
62
|
+
// Close the WebSocket connection
|
|
63
|
+
this.beaconWebSocket.close();
|
|
64
|
+
|
|
65
|
+
// Clean up event listeners
|
|
66
|
+
this.beaconWebSocket.onopen = null;
|
|
67
|
+
this.beaconWebSocket.onmessage = null;
|
|
68
|
+
this.beaconWebSocket.onerror = null;
|
|
69
|
+
this.beaconWebSocket.onclose = null;
|
|
70
|
+
|
|
71
|
+
// Set WebSocket reference to null to free up memory
|
|
72
|
+
this.beaconWebSocket = null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Clear the reconnect timeout if it exists
|
|
76
|
+
if (this.reconnectTimeout) {
|
|
77
|
+
clearTimeout(this.reconnectTimeout);
|
|
78
|
+
this.reconnectTimeout = null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log("Beacon WebSocket connection closed.");
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Method for reconnection to beacon websocket
|
|
86
|
+
reconnectBeaconWebSocket() {
|
|
87
|
+
if (this.reconnectTimeout) {
|
|
88
|
+
clearTimeout(this.reconnectTimeout);
|
|
89
|
+
}
|
|
90
|
+
this.reconnectTimeout = setTimeout(() => {
|
|
91
|
+
this.connectBeaconWebSocket();
|
|
92
|
+
}, this.reconnectInterval); // Retry connection after the reconnection interval
|
|
93
|
+
|
|
94
|
+
// Increase reconnection time by 5s, the limit is 60s (so that we dont overload the server)
|
|
95
|
+
if ((this.reconnectInterval + 5000) <= 60000) {
|
|
96
|
+
this.reconnectInterval += 5000;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Method for distributing the data into Application store
|
|
101
|
+
distributeData(data) {
|
|
102
|
+
const transformedData = this.transformData(data);
|
|
103
|
+
// TODO: use a pubsub instead of the appstore dispatch
|
|
104
|
+
this.App?.AppStore?.dispatch?.({ type: SET_ATTENTION_REQUIRED_BEACON, beacon: transformedData });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Transform and group beacon data
|
|
108
|
+
transformData(inputData) {
|
|
109
|
+
// Validate if input data are array
|
|
110
|
+
if (!Array.isArray(inputData)) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return inputData.reduce((acc, entry) => {
|
|
115
|
+
const { type, _c, reference_path } = entry;
|
|
116
|
+
|
|
117
|
+
// Identify the dynamic key (it could be 'library', 'configuration', 'services', etc.)
|
|
118
|
+
const dynamicKey = Object.keys(entry).find(key => (typeof entry[key] === 'object') && (entry[key] !== null) && !Array.isArray(entry[key]));
|
|
119
|
+
|
|
120
|
+
if (!dynamicKey) {
|
|
121
|
+
// Skip if no valid dynamic key is found
|
|
122
|
+
return acc;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const data = entry[dynamicKey];
|
|
126
|
+
// Ensure type is present in the accumulator
|
|
127
|
+
if (!acc[type]) {
|
|
128
|
+
acc[type] = {
|
|
129
|
+
count: 0,
|
|
130
|
+
data: []
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
// Push each entry into the data array
|
|
134
|
+
acc[type].data.push(data);
|
|
135
|
+
// Increment count for the type
|
|
136
|
+
acc[type].count += 1;
|
|
137
|
+
|
|
138
|
+
return acc;
|
|
139
|
+
}, {});
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -169,7 +169,7 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
169
169
|
type: _actions.types.AUTH_RESOURCES,
|
|
170
170
|
resources: resources
|
|
171
171
|
});
|
|
172
|
-
|
|
172
|
+
_this.validateNavigation({
|
|
173
173
|
resources
|
|
174
174
|
});
|
|
175
175
|
}
|
|
@@ -263,75 +263,57 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
263
263
|
window.location.reload();
|
|
264
264
|
});
|
|
265
265
|
}
|
|
266
|
-
|
|
267
|
-
// TODO: reconsider removing async/await with promise
|
|
268
266
|
validateNavigation(_ref) {
|
|
269
|
-
var
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
267
|
+
var _state$navigation, _this$App$AppStore$di, _this$App$AppStore;
|
|
268
|
+
var {
|
|
269
|
+
resources
|
|
270
|
+
} = _ref;
|
|
271
|
+
var state = this.App.AppStore.getState();
|
|
272
|
+
var navItems = (_state$navigation = state.navigation) === null || _state$navigation === void 0 ? void 0 : _state$navigation.navItems;
|
|
273
|
+
var authorizedNavItems = [];
|
|
274
|
+
navItems && navItems.map((itm, idx) => {
|
|
275
|
+
if (resources.indexOf('authz:superuser') !== -1) {
|
|
276
|
+
// If user is superuser, validate every navigation item
|
|
277
|
+
authorizedNavItems.push(itm);
|
|
278
|
+
} else {
|
|
279
|
+
if (itm.resource) {
|
|
280
|
+
if (itm.children) {
|
|
281
|
+
itm.children = this._validateChildrenNav(itm, resources);
|
|
282
|
+
}
|
|
283
|
+
// Item validation
|
|
284
|
+
var access_auth = this._validateItemNav(itm.resource, resources);
|
|
285
|
+
if (access_auth == true) {
|
|
282
286
|
authorizedNavItems.push(itm);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
var access_auth = _this3._validateItemNav(itm.resource, resources);
|
|
290
|
-
if (access_auth == true) {
|
|
291
|
-
authorizedNavItems.push(itm);
|
|
292
|
-
}
|
|
293
|
-
} else {
|
|
294
|
-
if (itm.children) {
|
|
295
|
-
itm.children = yield _this3._validateChildrenNav(itm, resources);
|
|
296
|
-
if (itm.children.length > 0) {
|
|
297
|
-
authorizedNavItems.push(itm);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
if (itm.children) {
|
|
290
|
+
itm.children = this._validateChildrenNav(itm, resources);
|
|
291
|
+
if (itm.children.length > 0) {
|
|
292
|
+
authorizedNavItems.push(itm);
|
|
300
293
|
}
|
|
301
294
|
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
navItems: authorizedNavItems
|
|
310
|
-
});
|
|
311
|
-
})();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
(_this$App$AppStore$di = (_this$App$AppStore = this.App.AppStore).dispatch) === null || _this$App$AppStore$di === void 0 || _this$App$AppStore$di.call(_this$App$AppStore, {
|
|
299
|
+
type: _actions2.SET_NAVIGATION_ITEMS,
|
|
300
|
+
navItems: authorizedNavItems
|
|
301
|
+
});
|
|
312
302
|
}
|
|
313
303
|
|
|
314
304
|
// Validate sidebar's item children
|
|
315
305
|
_validateChildrenNav(itm, resources) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
return function (_x3, _x4) {
|
|
330
|
-
return _ref3.apply(this, arguments);
|
|
331
|
-
};
|
|
332
|
-
}()));
|
|
333
|
-
return authorizedNavChildren;
|
|
334
|
-
})();
|
|
306
|
+
// Item's children validation
|
|
307
|
+
var authorizedNavChildren = [];
|
|
308
|
+
itm.children.map((child, id) => {
|
|
309
|
+
if (child.resource) {
|
|
310
|
+
var access_auth = this._validateItemNav(child.resource, resources);
|
|
311
|
+
if (access_auth == true) {
|
|
312
|
+
authorizedNavChildren.push(child);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
return authorizedNavChildren;
|
|
335
317
|
}
|
|
336
318
|
|
|
337
319
|
// Validate sidebar items
|
|
@@ -361,38 +343,38 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
361
343
|
return valid;
|
|
362
344
|
}
|
|
363
345
|
updateUserInfo() {
|
|
364
|
-
var
|
|
346
|
+
var _this3 = this;
|
|
365
347
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
366
348
|
var _response$data;
|
|
367
349
|
var response;
|
|
368
350
|
try {
|
|
369
|
-
response = yield
|
|
351
|
+
response = yield _this3.Api.userinfo(_this3.OAuthTokens.access_token);
|
|
370
352
|
} catch (err) {
|
|
371
353
|
console.error("Failed to update user info", err);
|
|
372
|
-
|
|
373
|
-
if (
|
|
374
|
-
var
|
|
375
|
-
(
|
|
354
|
+
_this3.UserInfo = null;
|
|
355
|
+
if (_this3.App.AppStore) {
|
|
356
|
+
var _this3$App$AppStore$d, _this3$App$AppStore;
|
|
357
|
+
(_this3$App$AppStore$d = (_this3$App$AppStore = _this3.App.AppStore).dispatch) === null || _this3$App$AppStore$d === void 0 || _this3$App$AppStore$d.call(_this3$App$AppStore, {
|
|
376
358
|
type: _actions.types.AUTH_USERINFO,
|
|
377
|
-
payload:
|
|
359
|
+
payload: _this3.UserInfo
|
|
378
360
|
});
|
|
379
361
|
}
|
|
380
362
|
return false;
|
|
381
363
|
}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
var
|
|
386
|
-
(
|
|
364
|
+
_this3.UserInfo = response.data;
|
|
365
|
+
_this3.SessionExpiration = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.exp;
|
|
366
|
+
if (_this3.App.AppStore) {
|
|
367
|
+
var _this3$App$AppStore$d2, _this3$App$AppStore2;
|
|
368
|
+
(_this3$App$AppStore$d2 = (_this3$App$AppStore2 = _this3.App.AppStore).dispatch) === null || _this3$App$AppStore$d2 === void 0 || _this3$App$AppStore$d2.call(_this3$App$AppStore2, {
|
|
387
369
|
type: _actions.types.AUTH_USERINFO,
|
|
388
|
-
payload:
|
|
370
|
+
payload: _this3.UserInfo
|
|
389
371
|
});
|
|
390
372
|
}
|
|
391
373
|
|
|
392
374
|
/** Check for TenantService and pass tenants list obtained from userinfo */
|
|
393
|
-
var availableTenants =
|
|
394
|
-
if (
|
|
395
|
-
yield
|
|
375
|
+
var availableTenants = _this3.UserInfo.tenants;
|
|
376
|
+
if (_this3.App.Services.TenantService) {
|
|
377
|
+
yield _this3.App.Services.TenantService.setTenants(availableTenants, _this3._getAuthorizedTenant(_this3.UserInfo));
|
|
396
378
|
}
|
|
397
379
|
return true;
|
|
398
380
|
})();
|
|
@@ -400,11 +382,11 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
400
382
|
|
|
401
383
|
// Method for obtaining and storing the OAuth tokens based on authorization code
|
|
402
384
|
_exchangeCodeForTokens(authorization_code) {
|
|
403
|
-
var
|
|
385
|
+
var _this4 = this;
|
|
404
386
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
405
387
|
try {
|
|
406
|
-
var response = yield
|
|
407
|
-
|
|
388
|
+
var response = yield _this4.Api.token_authorization_code(authorization_code, _this4.RedirectURL);
|
|
389
|
+
_this4.OAuthTokens = response.data;
|
|
408
390
|
sessionStorage.setItem('SeaCatOAuth2Tokens', JSON.stringify(response.data));
|
|
409
391
|
return true;
|
|
410
392
|
} catch (err) {
|
|
@@ -416,16 +398,16 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
416
398
|
|
|
417
399
|
// Method for refreshing OAuth tokens
|
|
418
400
|
_refreshTokens() {
|
|
419
|
-
var
|
|
401
|
+
var _this5 = this;
|
|
420
402
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
421
|
-
var
|
|
403
|
+
var _this5$OAuthTokens;
|
|
422
404
|
// If no refresh_token found, return false
|
|
423
|
-
if (!((
|
|
405
|
+
if (!((_this5$OAuthTokens = _this5.OAuthTokens) !== null && _this5$OAuthTokens !== void 0 && _this5$OAuthTokens.refresh_token)) {
|
|
424
406
|
return false;
|
|
425
407
|
}
|
|
426
408
|
try {
|
|
427
|
-
var response = yield
|
|
428
|
-
|
|
409
|
+
var response = yield _this5.Api.token_refresh(_this5.OAuthTokens.refresh_token);
|
|
410
|
+
_this5.OAuthTokens = response.data;
|
|
429
411
|
sessionStorage.setItem('SeaCatOAuth2Tokens', JSON.stringify(response.data));
|
|
430
412
|
return true;
|
|
431
413
|
} catch (err) {
|
|
@@ -452,9 +434,9 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
452
434
|
|
|
453
435
|
// Loop validating session expiration
|
|
454
436
|
_startSessionExpirationValidation() {
|
|
455
|
-
var
|
|
437
|
+
var _this6 = this;
|
|
456
438
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
457
|
-
if (!
|
|
439
|
+
if (!_this6.SessionExpiration) {
|
|
458
440
|
console.warn("Session expiration is not set.");
|
|
459
441
|
return;
|
|
460
442
|
}
|
|
@@ -463,7 +445,7 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
463
445
|
var MAX_SESSION_DURATION = Math.pow(2, 31) - 1;
|
|
464
446
|
|
|
465
447
|
// Proactivelly validate session expiration
|
|
466
|
-
var lastKnownExpiration =
|
|
448
|
+
var lastKnownExpiration = _this6.SessionExpiration; // Last known session expiration
|
|
467
449
|
var sessionStartTime = Date.now() / 1000; // Session start time
|
|
468
450
|
var sessionDuration = lastKnownExpiration - sessionStartTime; // Session duration
|
|
469
451
|
// Prevent glitches on very large time remaining values
|
|
@@ -476,9 +458,9 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
476
458
|
var warningDisplayed = false; // Tracks if the "about to expire" warning has been shown
|
|
477
459
|
|
|
478
460
|
var _validateSession = /*#__PURE__*/function () {
|
|
479
|
-
var
|
|
461
|
+
var _ref2 = (0, _asyncToGenerator2.default)(function* () {
|
|
480
462
|
var currentTime = Date.now() / 1000; // Convert milliseconds to seconds
|
|
481
|
-
var timeRemaining =
|
|
463
|
+
var timeRemaining = _this6.SessionExpiration - currentTime; // Time difference for triggering "about to expire" warning
|
|
482
464
|
// Prevent glitches on very large time remaining values
|
|
483
465
|
if (timeRemaining > MAX_SESSION_DURATION) {
|
|
484
466
|
// Set timeout to maximum allowed value
|
|
@@ -488,13 +470,13 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
488
470
|
// Validate session on half of the session expiration or if the remaining time is <= 5min
|
|
489
471
|
if (!refreshSessionDone && (timeRemaining <= 300 || currentTime >= sessionMidpoint)) {
|
|
490
472
|
refreshSessionDone = true;
|
|
491
|
-
var tokensRefreshed = yield
|
|
473
|
+
var tokensRefreshed = yield _this6._refreshTokens();
|
|
492
474
|
// Recalculate if session expiration was extended
|
|
493
475
|
if (tokensRefreshed) {
|
|
494
|
-
yield
|
|
476
|
+
yield _this6.updateUserInfo(); // Update userinfo
|
|
495
477
|
// If current session expiration differs from last known expiration, recalculate session variables
|
|
496
|
-
if (
|
|
497
|
-
lastKnownExpiration =
|
|
478
|
+
if (_this6.SessionExpiration !== lastKnownExpiration) {
|
|
479
|
+
lastKnownExpiration = _this6.SessionExpiration;
|
|
498
480
|
sessionStartTime = currentTime;
|
|
499
481
|
sessionDuration = lastKnownExpiration - sessionStartTime;
|
|
500
482
|
// Prevent glitches on very large time remaining values
|
|
@@ -510,31 +492,31 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
510
492
|
|
|
511
493
|
// If remaining time is between 1 and 60s, repetitivelly ask for userInfo and trigger "about to expire" warning
|
|
512
494
|
if (timeRemaining <= 60 && timeRemaining > 0) {
|
|
513
|
-
var _tokensRefreshed = yield
|
|
514
|
-
yield
|
|
495
|
+
var _tokensRefreshed = yield _this6._refreshTokens(); // Returns true/false if token is refreshed/not refreshed
|
|
496
|
+
yield _this6.updateUserInfo(); // Continue updating user info
|
|
515
497
|
if (!_tokensRefreshed && !warningDisplayed) {
|
|
516
|
-
|
|
498
|
+
_this6.App.addAlert("info", "General|Your session will expire soon", 30, true);
|
|
517
499
|
warningDisplayed = true; // Mark the warning as displayed
|
|
518
500
|
}
|
|
519
501
|
}
|
|
520
502
|
|
|
521
503
|
// Validation on expired session
|
|
522
|
-
if (
|
|
504
|
+
if (_this6.SessionExpiration <= currentTime) {
|
|
523
505
|
// Handle refresh token prior updating user info
|
|
524
|
-
yield
|
|
506
|
+
yield _this6._refreshTokens();
|
|
525
507
|
// Handle session expiration
|
|
526
|
-
var isUserInfoUpdated = yield
|
|
508
|
+
var isUserInfoUpdated = yield _this6.updateUserInfo();
|
|
527
509
|
if (!isUserInfoUpdated) {
|
|
528
510
|
// Stop further checks
|
|
529
|
-
clearTimeout(
|
|
530
|
-
|
|
531
|
-
|
|
511
|
+
clearTimeout(_this6.sessionValidationInterval);
|
|
512
|
+
_this6.sessionValidationInterval = null;
|
|
513
|
+
_this6.App.addAlert("info", "ASABAuthModule|Your session has expired.", 3600 * 1000, true, alert => /*#__PURE__*/_react.default.createElement(_SessionExpirationAlert.SessionExpirationAlert, {
|
|
532
514
|
alert: alert
|
|
533
515
|
}));
|
|
534
516
|
// Disable UI elements
|
|
535
|
-
if (
|
|
536
|
-
var
|
|
537
|
-
(
|
|
517
|
+
if (_this6.App.AppStore) {
|
|
518
|
+
var _this6$App$AppStore$d, _this6$App$AppStore;
|
|
519
|
+
(_this6$App$AppStore$d = (_this6$App$AppStore = _this6.App.AppStore).dispatch) === null || _this6$App$AppStore$d === void 0 || _this6$App$AppStore$d.call(_this6$App$AppStore, {
|
|
538
520
|
type: _actions.types.AUTH_SESSION_EXPIRATION,
|
|
539
521
|
sessionExpired: true
|
|
540
522
|
});
|
|
@@ -555,10 +537,10 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
555
537
|
}
|
|
556
538
|
|
|
557
539
|
// Re-trigger validation after 10 seconds
|
|
558
|
-
|
|
540
|
+
_this6.sessionValidationInterval = setTimeout(_validateSession, 10000);
|
|
559
541
|
});
|
|
560
542
|
return function validateSession() {
|
|
561
|
-
return
|
|
543
|
+
return _ref2.apply(this, arguments);
|
|
562
544
|
};
|
|
563
545
|
}();
|
|
564
546
|
|
|
@@ -126,7 +126,7 @@ class TenantService extends _asab_webui_components.Service {
|
|
|
126
126
|
// getCurrentTenant() method is used for obtaining current tenant
|
|
127
127
|
getCurrentTenant() {
|
|
128
128
|
var _this$App, _state$tenant;
|
|
129
|
-
var state = (_this$App = this.App) === null || _this$App === void 0 || (_this$App = _this$App.AppStore) === null || _this$App === void 0 ? void 0 : _this$App.
|
|
129
|
+
var state = (_this$App = this.App) === null || _this$App === void 0 || (_this$App = _this$App.AppStore) === null || _this$App === void 0 ? void 0 : _this$App.getState();
|
|
130
130
|
var currentTenant = state === null || state === void 0 || (_state$tenant = state.tenant) === null || _state$tenant === void 0 ? void 0 : _state$tenant.current;
|
|
131
131
|
// If current tenant is not in Application store yet, get it from the URL params
|
|
132
132
|
if (!currentTenant) {
|
package/package.json
CHANGED
|
File without changes
|