asab_webui_shell 25.2.6 → 25.2.7
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/modules/auth/api.js +10 -0
- package/dist/modules/auth/index.js +94 -31
- package/package.json +1 -1
package/dist/modules/auth/api.js
CHANGED
|
@@ -105,6 +105,16 @@ class SeaCatAuthApi {
|
|
|
105
105
|
});
|
|
106
106
|
return this.OidcAPI.post('/token', qs.toString());
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
// Method for token refresh
|
|
110
|
+
token_refresh(refresh_token) {
|
|
111
|
+
var qs = new URLSearchParams({
|
|
112
|
+
grant_type: "refresh_token",
|
|
113
|
+
refresh_token: refresh_token,
|
|
114
|
+
client_id: this.ClientId
|
|
115
|
+
});
|
|
116
|
+
return this.OidcAPI.post('/token', qs.toString());
|
|
117
|
+
}
|
|
108
118
|
}
|
|
109
119
|
exports.SeaCatAuthApi = SeaCatAuthApi;
|
|
110
120
|
;
|
|
@@ -21,7 +21,7 @@ var InvitationScreen = /*#__PURE__*/(0, _react.lazy)(() => Promise.resolve().the
|
|
|
21
21
|
class AuthModule extends _asab_webui_components.Module {
|
|
22
22
|
constructor(app, name) {
|
|
23
23
|
super(app, "AuthModule");
|
|
24
|
-
this.
|
|
24
|
+
this.OAuthTokens = JSON.parse(sessionStorage.getItem('SeaCatOAuth2Tokens'));
|
|
25
25
|
this.UserInfo = null;
|
|
26
26
|
this.Api = new _api.SeaCatAuthApi(app);
|
|
27
27
|
this.RedirectURL = window.location.href;
|
|
@@ -89,7 +89,7 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
if (authorization_code !== null) {
|
|
92
|
-
yield _this.
|
|
92
|
+
yield _this._exchangeCodeForTokens(authorization_code);
|
|
93
93
|
// Remove 'code' from a query string
|
|
94
94
|
qs.delete('code');
|
|
95
95
|
var stateIndex = qs.get("state");
|
|
@@ -121,12 +121,12 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
// Do we have an oauth token (we are authorized to use the app)
|
|
124
|
-
if (_this.
|
|
124
|
+
if (_this.OAuthTokens != null) {
|
|
125
125
|
// Update the user info
|
|
126
126
|
var result = yield _this.updateUserInfo();
|
|
127
127
|
if (!result) {
|
|
128
128
|
// User info not found - go to login
|
|
129
|
-
sessionStorage.removeItem('
|
|
129
|
+
sessionStorage.removeItem('SeaCatOAuth2Tokens');
|
|
130
130
|
var force_login_prompt = true;
|
|
131
131
|
yield _this.Api.login(_this.RedirectURL, force_login_prompt);
|
|
132
132
|
return;
|
|
@@ -188,13 +188,13 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
188
188
|
}
|
|
189
189
|
authInterceptor() {
|
|
190
190
|
var interceptor = config => {
|
|
191
|
-
config.headers['Authorization'] = 'Bearer ' + this.
|
|
191
|
+
config.headers['Authorization'] = 'Bearer ' + this.OAuthTokens['access_token'];
|
|
192
192
|
return config;
|
|
193
193
|
};
|
|
194
194
|
return interceptor;
|
|
195
195
|
}
|
|
196
196
|
webSocketAuthInterceptor() {
|
|
197
|
-
return "access_token_".concat(this.
|
|
197
|
+
return "access_token_".concat(this.OAuthTokens['access_token']);
|
|
198
198
|
}
|
|
199
199
|
simulateUserinfo(mock_userinfo) {
|
|
200
200
|
var _this2 = this;
|
|
@@ -250,8 +250,8 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
250
250
|
this.App.addSplashScreenRequestor(this);
|
|
251
251
|
this._stopSessionExpirationValidation(); // Stop session validation and clear the timeout
|
|
252
252
|
|
|
253
|
-
sessionStorage.removeItem('
|
|
254
|
-
var promise = this.Api.logout(this.
|
|
253
|
+
sessionStorage.removeItem('SeaCatOAuth2Tokens');
|
|
254
|
+
var promise = this.Api.logout(this.OAuthTokens['access_token']);
|
|
255
255
|
if (promise == null) {
|
|
256
256
|
window.location.reload();
|
|
257
257
|
}
|
|
@@ -362,7 +362,7 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
362
362
|
var _response$data;
|
|
363
363
|
var response;
|
|
364
364
|
try {
|
|
365
|
-
response = yield _this5.Api.userinfo(_this5.
|
|
365
|
+
response = yield _this5.Api.userinfo(_this5.OAuthTokens.access_token);
|
|
366
366
|
} catch (err) {
|
|
367
367
|
console.error("Failed to update user info", err);
|
|
368
368
|
_this5.UserInfo = null;
|
|
@@ -391,19 +391,41 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
391
391
|
return true;
|
|
392
392
|
})();
|
|
393
393
|
}
|
|
394
|
-
|
|
394
|
+
|
|
395
|
+
// Method for obtaining and storing the OAuth tokens based on authorization code
|
|
396
|
+
_exchangeCodeForTokens(authorization_code) {
|
|
395
397
|
var _this6 = this;
|
|
396
398
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
397
|
-
var response;
|
|
398
399
|
try {
|
|
399
|
-
response = yield _this6.Api.token_authorization_code(authorization_code, _this6.RedirectURL);
|
|
400
|
+
var response = yield _this6.Api.token_authorization_code(authorization_code, _this6.RedirectURL);
|
|
401
|
+
_this6.OAuthTokens = response.data;
|
|
402
|
+
sessionStorage.setItem('SeaCatOAuth2Tokens', JSON.stringify(response.data));
|
|
403
|
+
return true;
|
|
400
404
|
} catch (err) {
|
|
401
405
|
console.error("Failed to update token", err);
|
|
402
406
|
return false;
|
|
403
407
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
408
|
+
})();
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// Method for refreshing OAuth tokens
|
|
412
|
+
_refreshTokens() {
|
|
413
|
+
var _this7 = this;
|
|
414
|
+
return (0, _asyncToGenerator2.default)(function* () {
|
|
415
|
+
var _this7$OAuthTokens;
|
|
416
|
+
// If no refresh_token found, return false
|
|
417
|
+
if (!((_this7$OAuthTokens = _this7.OAuthTokens) !== null && _this7$OAuthTokens !== void 0 && _this7$OAuthTokens.refresh_token)) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
try {
|
|
421
|
+
var response = yield _this7.Api.token_refresh(_this7.OAuthTokens.refresh_token);
|
|
422
|
+
_this7.OAuthTokens = response.data;
|
|
423
|
+
sessionStorage.setItem('SeaCatOAuth2Tokens', JSON.stringify(response.data));
|
|
424
|
+
return true;
|
|
425
|
+
} catch (err) {
|
|
426
|
+
console.error("Failed to refresh token", err);
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
407
429
|
})();
|
|
408
430
|
}
|
|
409
431
|
_getAuthorizedTenant(userInfo) {
|
|
@@ -424,48 +446,89 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
424
446
|
|
|
425
447
|
// Loop validating session expiration
|
|
426
448
|
_startSessionExpirationValidation() {
|
|
427
|
-
var
|
|
449
|
+
var _this8 = this;
|
|
428
450
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
429
|
-
if (!
|
|
451
|
+
if (!_this8.SessionExpiration) {
|
|
430
452
|
console.warn("Session expiration is not set.");
|
|
431
453
|
return;
|
|
432
454
|
}
|
|
455
|
+
|
|
456
|
+
// Max session duration
|
|
457
|
+
var MAX_SESSION_DURATION = Math.pow(2, 31) - 1;
|
|
458
|
+
|
|
459
|
+
// Proactivelly validate session expiration
|
|
460
|
+
var lastKnownExpiration = _this8.SessionExpiration; // Last known session expiration
|
|
461
|
+
var sessionStartTime = Date.now() / 1000; // Session start time
|
|
462
|
+
var sessionDuration = lastKnownExpiration - sessionStartTime; // Session duration
|
|
463
|
+
// Prevent glitches on very large time remaining values
|
|
464
|
+
if (sessionDuration > MAX_SESSION_DURATION) {
|
|
465
|
+
// Set timeout to maximum allowed value
|
|
466
|
+
sessionDuration = MAX_SESSION_DURATION;
|
|
467
|
+
}
|
|
468
|
+
var sessionMidpoint = sessionStartTime + sessionDuration / 2; // Session midpoint value
|
|
469
|
+
var refreshSessionDone = false; // Tracks if the session has been proactivelly refreshed
|
|
433
470
|
var warningDisplayed = false; // Tracks if the "about to expire" warning has been shown
|
|
434
471
|
|
|
435
472
|
var _validateSession = /*#__PURE__*/function () {
|
|
436
473
|
var _ref3 = (0, _asyncToGenerator2.default)(function* () {
|
|
437
474
|
var currentTime = Date.now() / 1000; // Convert milliseconds to seconds
|
|
438
|
-
var timeRemaining =
|
|
475
|
+
var timeRemaining = _this8.SessionExpiration - currentTime; // Time difference for triggering "about to expire" warning
|
|
439
476
|
// Prevent glitches on very large time remaining values
|
|
440
|
-
if (timeRemaining
|
|
477
|
+
if (timeRemaining > MAX_SESSION_DURATION) {
|
|
441
478
|
// Set timeout to maximum allowed value
|
|
442
|
-
timeRemaining =
|
|
479
|
+
timeRemaining = MAX_SESSION_DURATION;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Validate session on half of the session expiration or if the remaining time is <= 5min
|
|
483
|
+
if (!refreshSessionDone && (timeRemaining <= 300 || currentTime >= sessionMidpoint)) {
|
|
484
|
+
refreshSessionDone = true;
|
|
485
|
+
var tokensRefreshed = yield _this8._refreshTokens();
|
|
486
|
+
// Recalculate if session expiration was extended
|
|
487
|
+
if (tokensRefreshed) {
|
|
488
|
+
yield _this8.updateUserInfo(); // Update userinfo
|
|
489
|
+
// If current session expiration differs from last known expiration, recalculate session variables
|
|
490
|
+
if (_this8.SessionExpiration !== lastKnownExpiration) {
|
|
491
|
+
lastKnownExpiration = _this8.SessionExpiration;
|
|
492
|
+
sessionStartTime = currentTime;
|
|
493
|
+
sessionDuration = lastKnownExpiration - sessionStartTime;
|
|
494
|
+
// Prevent glitches on very large time remaining values
|
|
495
|
+
if (sessionDuration > MAX_SESSION_DURATION) {
|
|
496
|
+
// Set timeout to maximum allowed value
|
|
497
|
+
sessionDuration = MAX_SESSION_DURATION;
|
|
498
|
+
}
|
|
499
|
+
sessionMidpoint = sessionStartTime + sessionDuration / 2;
|
|
500
|
+
refreshSessionDone = false;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
443
503
|
}
|
|
444
504
|
|
|
445
505
|
// If remaining time is between 1 and 60s, repetitivelly ask for userInfo and trigger "about to expire" warning
|
|
446
506
|
if (timeRemaining <= 60 && timeRemaining > 0) {
|
|
447
|
-
|
|
448
|
-
|
|
507
|
+
var _tokensRefreshed = yield _this8._refreshTokens(); // Returns true/false if token is refreshed/not refreshed
|
|
508
|
+
yield _this8.updateUserInfo(); // Continue updating user info
|
|
509
|
+
if (!_tokensRefreshed && !warningDisplayed) {
|
|
510
|
+
_this8.App.addAlert("info", "General|Your session will expire soon", 30, true);
|
|
449
511
|
warningDisplayed = true; // Mark the warning as displayed
|
|
450
512
|
}
|
|
451
|
-
yield _this7.updateUserInfo(); // Continue updating user info
|
|
452
513
|
}
|
|
453
514
|
|
|
454
515
|
// Validation on expired session
|
|
455
|
-
if (
|
|
516
|
+
if (_this8.SessionExpiration <= currentTime) {
|
|
517
|
+
// Handle refresh token prior updating user info
|
|
518
|
+
yield _this8._refreshTokens();
|
|
456
519
|
// Handle session expiration
|
|
457
|
-
var isUserInfoUpdated = yield
|
|
520
|
+
var isUserInfoUpdated = yield _this8.updateUserInfo();
|
|
458
521
|
if (!isUserInfoUpdated) {
|
|
459
522
|
// Stop further checks
|
|
460
|
-
clearTimeout(
|
|
461
|
-
|
|
462
|
-
|
|
523
|
+
clearTimeout(_this8.sessionValidationInterval);
|
|
524
|
+
_this8.sessionValidationInterval = null;
|
|
525
|
+
_this8.App.addAlert("info", "ASABAuthModule|Your session has expired.", 3600 * 1000, true, (alert, store) => /*#__PURE__*/_react.default.createElement(_SessionExpirationAlert.SessionExpirationAlert, {
|
|
463
526
|
alert: alert,
|
|
464
527
|
store: store
|
|
465
528
|
}));
|
|
466
529
|
// Disable UI elements
|
|
467
|
-
if (
|
|
468
|
-
|
|
530
|
+
if (_this8.App.Store) {
|
|
531
|
+
_this8.App.Store.dispatch({
|
|
469
532
|
type: _actions.types.AUTH_SESSION_EXPIRATION,
|
|
470
533
|
sessionExpired: true
|
|
471
534
|
});
|
|
@@ -486,7 +549,7 @@ class AuthModule extends _asab_webui_components.Module {
|
|
|
486
549
|
}
|
|
487
550
|
|
|
488
551
|
// Re-trigger validation after 10 seconds
|
|
489
|
-
|
|
552
|
+
_this8.sessionValidationInterval = setTimeout(_validateSession, 10000);
|
|
490
553
|
});
|
|
491
554
|
return function validateSession() {
|
|
492
555
|
return _ref3.apply(this, arguments);
|