asab_webui_shell 27.4.4 → 27.5.0

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.
@@ -81,15 +81,24 @@ class SeaCatAuthApi {
81
81
  });
82
82
  }
83
83
  userinfo(access_token) {
84
- var userinfoPath = '/userinfo';
84
+ var internal = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
85
+ // 'internal' is a flag to indicate that the userinfo is requested from the internal API (SeaCat Auth API)
86
+ // instead of the public OpenID Connect API - that is used for the web app that runs inside of the cluser (asab-pyppeteer)
87
+
85
88
  var headers = {};
86
89
  // Add access bearer token to the Authorization headers
87
90
  if (access_token != null) {
88
91
  headers.Authorization = 'Bearer ' + access_token;
89
92
  }
90
- return this.OidcAPI.get(userinfoPath, {
91
- headers: headers
92
- });
93
+ if (internal) {
94
+ return this.SeaCatAuthAPI.get('/openidconnect/userinfo', {
95
+ headers: headers
96
+ });
97
+ } else {
98
+ return this.OidcAPI.get('/userinfo', {
99
+ headers: headers
100
+ });
101
+ }
93
102
  }
94
103
  token_authorization_code(authorization_code, redirect_uri) {
95
104
  var redirectUri = new URL(redirect_uri);
@@ -14,13 +14,28 @@ var _actions = require("./actions");
14
14
  var _actions2 = require("../../actions");
15
15
  var _api = require("./api");
16
16
  var _locationReplace = require("../../components/locationReplace");
17
+ var _extractTenantFromUrl = require("../../utils/extractTenantFromUrl");
17
18
  var _SessionExpirationAlert = require("./components/SessionExpirationAlert");
18
19
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } // TODO: Use SessionExpirationAlert only after proper fix of the component
19
20
  var AccessControlScreen = /*#__PURE__*/(0, _react.lazy)(() => Promise.resolve().then(() => _interopRequireWildcard(require("./screens/AccessControlScreen"))));
20
21
  class AuthModule extends _asab_webui_components.Module {
21
22
  constructor(app, name) {
22
23
  super(app, "AuthModule");
23
- this.OAuthTokens = JSON.parse(sessionStorage.getItem('SeaCatOAuth2Tokens'));
24
+ if (typeof OAUTH_TOKENS !== 'undefined') {
25
+ // Read OAuth tokens from webpack.dev.js settings ... this is development mode only
26
+ // Example from webpack.dev.js:
27
+ // new webpack.DefinePlugin({
28
+ // ....
29
+ // 'OAUTH_TOKENS': JSON.stringify({
30
+ // "internal": true,
31
+ // "access_token": "eyJh...SbVaw"
32
+ // })
33
+ // }),
34
+ this.OAuthTokens = OAUTH_TOKENS;
35
+ } else {
36
+ // Read OAuth tokens from session storage
37
+ this.OAuthTokens = JSON.parse(sessionStorage.getItem('SeaCatOAuth2Tokens'));
38
+ }
24
39
  this.UserInfo = null;
25
40
  this.Api = new _api.SeaCatAuthApi(app);
26
41
  this.RedirectURL = window.location.href;
@@ -327,27 +342,71 @@ class AuthModule extends _asab_webui_components.Module {
327
342
  updateUserInfo() {
328
343
  var _this3 = this;
329
344
  return (0, _asyncToGenerator2.default)(function* () {
330
- var _response$data;
331
- var response;
332
- try {
333
- response = yield _this3.Api.userinfo(_this3.OAuthTokens.access_token);
334
- } catch (err) {
335
- console.error("Failed to update user info", err);
336
- _this3.UserInfo = null;
337
- if (_this3.App.AppStore) {
338
- var _this3$App$AppStore$d, _this3$App$AppStore;
339
- (_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, {
340
- type: _actions.types.AUTH_USERINFO,
341
- payload: _this3.UserInfo
342
- });
345
+ var internal = _this3.OAuthTokens.internal || false;
346
+ if (!internal) {
347
+ var _response$data;
348
+ var response;
349
+ try {
350
+ response = yield _this3.Api.userinfo(_this3.OAuthTokens.access_token);
351
+ } catch (err) {
352
+ console.error("Failed to update user info", err);
353
+ _this3.UserInfo = null;
354
+ if (_this3.App.AppStore) {
355
+ var _this3$App$AppStore$d, _this3$App$AppStore;
356
+ (_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, {
357
+ type: _actions.types.AUTH_USERINFO,
358
+ payload: _this3.UserInfo
359
+ });
360
+ }
361
+ return false;
343
362
  }
344
- return false;
363
+ _this3.UserInfo = response.data;
364
+ _this3.SessionExpiration = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.exp;
365
+ } else {
366
+ var _response$data2;
367
+ var _response;
368
+ try {
369
+ _response = yield _this3.Api.userinfo(_this3.OAuthTokens.access_token, internal);
370
+ } catch (err) {
371
+ console.error("Failed to update user info", err);
372
+ _this3.UserInfo = null;
373
+ if (_this3.App.AppStore) {
374
+ var _this3$App$AppStore$d2, _this3$App$AppStore2;
375
+ (_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, {
376
+ type: _actions.types.AUTH_USERINFO,
377
+ payload: _this3.UserInfo
378
+ });
379
+ }
380
+ return false;
381
+ }
382
+ _this3.UserInfo = _response.data;
383
+
384
+ // If the resource is `{'*': [....]}` then it is a global resources token (i.e. for API keys)
385
+ var resources = _response.data.resources;
386
+ var isGlobalResources = resources != null && typeof resources === 'object' && !Array.isArray(resources) && Object.keys(resources).length === 1 && Array.isArray(resources['*']);
387
+ if (isGlobalResources) {
388
+ var tenant = (0, _extractTenantFromUrl.extractTenantFromUrl)();
389
+ if (tenant) {
390
+ // Monkey patch the userinfo to add the tenant and resources
391
+ _this3.UserInfo['tenants'] = [tenant];
392
+ _this3.UserInfo['resources'][tenant] = resources['*'];
393
+ } else {
394
+ var _this3$App, _this3$App$dispatch;
395
+ console.error("Tenant not found in URL - if the global resources token is used, the tenant must be specified in the URL");
396
+ _this3.UserInfo = null;
397
+ _this3.SessionExpiration = null;
398
+ (_this3$App = _this3.App) === null || _this3$App === void 0 || (_this3$App = _this3$App.AppStore) === null || _this3$App === void 0 || (_this3$App$dispatch = _this3$App.dispatch) === null || _this3$App$dispatch === void 0 || _this3$App$dispatch.call(_this3$App, {
399
+ type: _actions.types.AUTH_USERINFO,
400
+ payload: null
401
+ });
402
+ return false;
403
+ }
404
+ }
405
+ _this3.SessionExpiration = (_response$data2 = _response.data) === null || _response$data2 === void 0 ? void 0 : _response$data2.exp;
345
406
  }
346
- _this3.UserInfo = response.data;
347
- _this3.SessionExpiration = (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.exp;
348
407
  if (_this3.App.AppStore) {
349
- var _this3$App$AppStore$d2, _this3$App$AppStore2;
350
- (_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, {
408
+ var _this3$App$AppStore$d3, _this3$App$AppStore3;
409
+ (_this3$App$AppStore$d3 = (_this3$App$AppStore3 = _this3.App.AppStore).dispatch) === null || _this3$App$AppStore$d3 === void 0 || _this3$App$AppStore$d3.call(_this3$App$AppStore3, {
351
410
  type: _actions.types.AUTH_USERINFO,
352
411
  payload: _this3.UserInfo
353
412
  });
@@ -9,6 +9,7 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
9
9
  var _asab_webui_components = require("asab_webui_components");
10
10
  var _actions = require("./actions");
11
11
  var _locationReplace = require("../../components/locationReplace");
12
+ var _extractTenantFromUrl = require("../../utils/extractTenantFromUrl");
12
13
  class TenantService extends _asab_webui_components.Service {
13
14
  constructor(app) {
14
15
  var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'TenantService';
@@ -43,7 +44,7 @@ class TenantService extends _asab_webui_components.Service {
43
44
  var _this2$App, _this2$App$dispatch;
44
45
  var authorizedTenant = _arguments.length > 1 && _arguments[1] !== undefined ? _arguments[1] : undefined;
45
46
  // Extract the current tenant from URL params
46
- var tenantFromUrl = _this2._extractTenantFromUrl();
47
+ var tenantFromUrl = (0, _extractTenantFromUrl.extractTenantFromUrl)();
47
48
 
48
49
  /* If tenant has not been provided in access URL, insert the authorized tenant
49
50
  or the first available tenant into the URL and reload the application */
@@ -130,17 +131,9 @@ class TenantService extends _asab_webui_components.Service {
130
131
  var currentTenant = state === null || state === void 0 || (_state$tenant = state.tenant) === null || _state$tenant === void 0 ? void 0 : _state$tenant.current;
131
132
  // If current tenant is not in Application store yet, get it from the URL params
132
133
  if (!currentTenant) {
133
- currentTenant = this._extractTenantFromUrl();
134
+ currentTenant = (0, _extractTenantFromUrl.extractTenantFromUrl)();
134
135
  }
135
136
  return currentTenant;
136
137
  }
137
-
138
- // Extract tenant from URL params
139
- _extractTenantFromUrl() {
140
- var search = window.location.search;
141
- var params = new URLSearchParams(search);
142
- var tenant = params.get('tenant');
143
- return tenant;
144
- }
145
138
  }
146
139
  exports.default = TenantService;
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = SuspenseScreen;
8
8
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
9
  var _react = _interopRequireWildcard(require("react"));
10
+ var _reactI18next = require("react-i18next");
10
11
  var _asab_webui_components = require("asab_webui_components");
11
12
  var _reactstrap = require("reactstrap");
12
13
  var _BrandImage = require("../components/branding/BrandImage");
@@ -18,6 +19,8 @@ function SuspenseScreen(props) {
18
19
  brandImage = _useState2[0],
19
20
  setBrandImage = _useState2[1];
20
21
  var theme = (0, _asab_webui_components.useAppSelector)(state => state.theme);
22
+ var _useTranslation = (0, _reactI18next.useTranslation)(),
23
+ t = _useTranslation.t;
21
24
  (0, _react.useEffect)(() => {
22
25
  setBrandImage((0, _BrandImage.getBrandImage)(props, theme));
23
26
  }, [theme]);
@@ -31,8 +34,8 @@ function SuspenseScreen(props) {
31
34
  }, brandImage ? /*#__PURE__*/_react.default.createElement("img", {
32
35
  className: "suspense-img",
33
36
  src: brandImage === null || brandImage === void 0 ? void 0 : brandImage.full,
34
- alt: "Loading..."
37
+ alt: "Loading"
35
38
  }) : /*#__PURE__*/_react.default.createElement("h2", {
36
39
  className: "text-center text-primary"
37
- }, "Loading...")), /*#__PURE__*/_react.default.createElement(_asab_webui_components.Spinner, null))));
40
+ }, t('General|Loading'))), /*#__PURE__*/_react.default.createElement(_asab_webui_components.Spinner, null))));
38
41
  }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.extractTenantFromUrl = extractTenantFromUrl;
7
+ function extractTenantFromUrl() {
8
+ var search = window.location.search;
9
+ var params = new URLSearchParams(search);
10
+ var tenant = params.get('tenant');
11
+ return tenant;
12
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "asab_webui_shell",
3
- "version": "27.4.4",
3
+ "version": "27.5.0",
4
4
  "license": "BSD-3-Clause",
5
5
  "description": "TeskaLabs ASAB WebUI Shell Application",
6
6
  "contributors": [