@singularsystems/neo-core 1.4.1 → 1.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.
- package/CHANGELOG.md +25 -0
- package/dist/AppServices/Config/ConfigModel.d.ts +6 -0
- package/dist/AppServices/Config/ConfigModel.js +7 -0
- package/dist/AppServices/Config/ConfigService.d.ts +1 -1
- package/dist/AppServices/Config/ConfigService.js +37 -15
- package/dist/AppServices/NeoModule.js +1 -1
- package/dist/AppServices/NeoTypes.d.ts +6 -2
- package/dist/AppServices/NeoTypes.js +4 -1
- package/dist/AppServices/index.d.ts +1 -1
- package/dist/Data/ApiDataSource.js +2 -1
- package/dist/Network/AppConnectionMonitor.d.ts +21 -0
- package/dist/Network/AppConnectionMonitor.js +145 -0
- package/dist/Network/ConnectionManager.d.ts +7 -0
- package/dist/Network/ConnectionManager.js +38 -0
- package/dist/Network/IAppConnectionMonitor.d.ts +6 -0
- package/dist/Network/IAppConnectionMonitor.js +1 -0
- package/dist/Network/IConnectionManager.d.ts +39 -0
- package/dist/Network/IConnectionManager.js +24 -0
- package/dist/Network/NetworkUtils.d.ts +11 -0
- package/dist/Network/NetworkUtils.js +29 -0
- package/dist/Network/index.d.ts +5 -0
- package/dist/Network/index.js +5 -0
- package/dist/Security/IAuthenticationService.d.ts +4 -2
- package/dist/Security/Oidc/OidcAuthService.d.ts +5 -8
- package/dist/Security/Oidc/OidcAuthService.js +80 -22
- package/dist/SignalR/HubBase.d.ts +1 -1
- package/dist/SignalR/HubBase.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Neo core changelog
|
|
2
2
|
|
|
3
|
+
## Version 1.5.0 (20 May 2026)
|
|
4
|
+
|
|
5
|
+
- Better offline support (see wiki "PWA Offline" guide for more details).
|
|
6
|
+
- Added `supportsOffline` to ConfigModel.
|
|
7
|
+
- Config service will now cache config data if `supportsOffline` is true.
|
|
8
|
+
- Network services
|
|
9
|
+
- Added `NetworkUtils` class for helping to identify whether the app can communicate with the server or not. Extends basic `navigator.onLine` property.
|
|
10
|
+
- Added `AppConnectionMonitor` base class for monitoring app connection, and allowing the app to reconnect when back online.
|
|
11
|
+
- OIDC Authentication service
|
|
12
|
+
- Will now redirect back to the current path if no path is specified.
|
|
13
|
+
- Will cache user data if `supportsOffline` is true.
|
|
14
|
+
- Current user and isAuthenticated properties will use cached data if available and if `supportsOffline` is true.
|
|
15
|
+
|
|
16
|
+
## Version 1.4.2 (11 May 2026)
|
|
17
|
+
|
|
18
|
+
- Authentication service
|
|
19
|
+
- Changed `loadUserFromSession` to try perform a silent sign in when the app is opened from another window.
|
|
20
|
+
- Change your startup code accordingly:
|
|
21
|
+
```diff
|
|
22
|
+
-if (config.isDevelopment) {
|
|
23
|
+
- await authService.loadUserFromSession();
|
|
24
|
+
-}
|
|
25
|
+
+await authService.loadUserFromSession();
|
|
26
|
+
```
|
|
27
|
+
|
|
3
28
|
## Version 1.4.1 (20 April 2026)
|
|
4
29
|
|
|
5
30
|
- Navigation helper
|
|
@@ -11,6 +11,11 @@ export interface IConfigModelData {
|
|
|
11
11
|
}
|
|
12
12
|
export interface IConfigModel extends IConfigModelData {
|
|
13
13
|
readonly isTestOrDevelopment: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Indicates that this app supports offline usage.
|
|
16
|
+
* If true, config and user data will be cached on fetch, and used when offline.
|
|
17
|
+
*/
|
|
18
|
+
readonly supportsOffline: boolean;
|
|
14
19
|
initialise(): void;
|
|
15
20
|
}
|
|
16
21
|
export default class ConfigModel implements IConfigModel {
|
|
@@ -18,6 +23,7 @@ export default class ConfigModel implements IConfigModel {
|
|
|
18
23
|
isDevelopment: boolean;
|
|
19
24
|
isTest: boolean;
|
|
20
25
|
get isTestOrDevelopment(): boolean;
|
|
26
|
+
get supportsOffline(): boolean;
|
|
21
27
|
get baseUrl(): string;
|
|
22
28
|
initialise(): void;
|
|
23
29
|
}
|
|
@@ -10,6 +10,13 @@ var ConfigModel = /** @class */ (function () {
|
|
|
10
10
|
enumerable: false,
|
|
11
11
|
configurable: true
|
|
12
12
|
});
|
|
13
|
+
Object.defineProperty(ConfigModel.prototype, "supportsOffline", {
|
|
14
|
+
get: function () {
|
|
15
|
+
return false;
|
|
16
|
+
},
|
|
17
|
+
enumerable: false,
|
|
18
|
+
configurable: true
|
|
19
|
+
});
|
|
13
20
|
Object.defineProperty(ConfigModel.prototype, "baseUrl", {
|
|
14
21
|
get: function () {
|
|
15
22
|
if (!this._baseUrl) {
|
|
@@ -6,7 +6,7 @@ export interface IConfigService {
|
|
|
6
6
|
* Load and process the config file from the specified path.
|
|
7
7
|
* Path will default to [baseUrl]/config.json
|
|
8
8
|
* @param path Optional path.
|
|
9
|
-
* @param store Offline store to allow offline retrieval.
|
|
9
|
+
* @param store Offline store to allow offline retrieval. Not necessary if you have set `supportsOffline` to true in the config model.
|
|
10
10
|
*/
|
|
11
11
|
loadConfig(path?: string, store?: IDbSet<IConfigModelData>): Promise<IConfigModel>;
|
|
12
12
|
/** Fetch the raw config data from the server. */
|
|
@@ -3,40 +3,62 @@ import { injectable, inject } from 'inversify';
|
|
|
3
3
|
import Axios from "axios";
|
|
4
4
|
import NeoTypes from '../NeoTypes';
|
|
5
5
|
import AxiosUtils from "../../AxiosUtils";
|
|
6
|
+
var storageKey = "neo-app-config-data";
|
|
6
7
|
var ConfigService = /** @class */ (function () {
|
|
7
8
|
function ConfigService(config) {
|
|
8
9
|
this.config = config;
|
|
9
10
|
}
|
|
10
11
|
ConfigService.prototype.loadConfig = function (path, store) {
|
|
11
12
|
return __awaiter(this, void 0, void 0, function () {
|
|
12
|
-
var configData, e_1;
|
|
13
|
+
var configData, e_1, storedConfig;
|
|
13
14
|
return __generator(this, function (_a) {
|
|
14
15
|
switch (_a.label) {
|
|
15
16
|
case 0:
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
if (!(!this.config.supportsOffline || navigator.onLine)) return [3 /*break*/, 7];
|
|
18
|
+
_a.label = 1;
|
|
18
19
|
case 1:
|
|
20
|
+
_a.trys.push([1, 6, , 7]);
|
|
21
|
+
return [4 /*yield*/, this.fetchConfig(path)];
|
|
22
|
+
case 2:
|
|
19
23
|
configData = (_a.sent()).data;
|
|
20
|
-
if (!store) return [3 /*break*/,
|
|
24
|
+
if (!store) return [3 /*break*/, 4];
|
|
21
25
|
return [4 /*yield*/, store.putAsync(configData, 1)];
|
|
22
|
-
case
|
|
26
|
+
case 3:
|
|
23
27
|
_a.sent();
|
|
24
|
-
|
|
25
|
-
case 3: return [3 /*break*/, 7];
|
|
28
|
+
return [3 /*break*/, 5];
|
|
26
29
|
case 4:
|
|
30
|
+
if (this.config.supportsOffline) {
|
|
31
|
+
localStorage.setItem(storageKey, JSON.stringify(configData));
|
|
32
|
+
}
|
|
33
|
+
_a.label = 5;
|
|
34
|
+
case 5: return [3 /*break*/, 7];
|
|
35
|
+
case 6:
|
|
27
36
|
e_1 = _a.sent();
|
|
28
|
-
if (!
|
|
37
|
+
if (!AxiosUtils.isNetworkError(e_1) || !(this.config.supportsOffline || store)) {
|
|
38
|
+
throw new Error("ConfigService - Error loading configuration: ".concat(e_1));
|
|
39
|
+
}
|
|
40
|
+
return [3 /*break*/, 7];
|
|
41
|
+
case 7:
|
|
42
|
+
if (!!configData) return [3 /*break*/, 11];
|
|
43
|
+
if (!store) return [3 /*break*/, 9];
|
|
29
44
|
return [4 /*yield*/, store.getAsync(1)];
|
|
30
|
-
case
|
|
31
|
-
// get config from index db
|
|
45
|
+
case 8:
|
|
32
46
|
configData = _a.sent();
|
|
33
|
-
|
|
34
|
-
case
|
|
47
|
+
return [3 /*break*/, 10];
|
|
48
|
+
case 9:
|
|
49
|
+
if (this.config.supportsOffline) {
|
|
50
|
+
storedConfig = localStorage.getItem(storageKey);
|
|
51
|
+
if (storedConfig) {
|
|
52
|
+
configData = JSON.parse(storedConfig);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
_a.label = 10;
|
|
56
|
+
case 10:
|
|
35
57
|
if (!configData) {
|
|
36
|
-
throw new Error("ConfigService -
|
|
58
|
+
throw new Error("ConfigService - Unable to load config data from offline storage.");
|
|
37
59
|
}
|
|
38
|
-
|
|
39
|
-
case
|
|
60
|
+
_a.label = 11;
|
|
61
|
+
case 11: return [2 /*return*/, this.setConfig(configData)];
|
|
40
62
|
}
|
|
41
63
|
});
|
|
42
64
|
});
|
|
@@ -6,7 +6,7 @@ import { TaskRunner, NotifyUtils } from '../';
|
|
|
6
6
|
import ModalStore from '../Components/Modal/ModalStore';
|
|
7
7
|
import { MenuItemProvider } from '../Routing/MenuItemProvider';
|
|
8
8
|
import { ErrorHandler } from '../Components/ErrorHandler';
|
|
9
|
-
import { ConnectionManager } from '../ConnectionManager';
|
|
9
|
+
import { ConnectionManager } from '../Network/ConnectionManager';
|
|
10
10
|
import LocalisationService from '../Localisation/LocalisationService';
|
|
11
11
|
import { NotificationHelper } from '../Components/Notifications/NotificationHelper';
|
|
12
12
|
import { RouteSecurityService } from "../Routing/RouteSecurityService";
|
|
@@ -10,7 +10,7 @@ import { IMenuItemProvider } from '../Routing/IMenuItemProvider';
|
|
|
10
10
|
import { IModalStore } from '../Components/Modal/ModalStore';
|
|
11
11
|
import { INotificationStore, INotificationHelper } from '../Components';
|
|
12
12
|
import { IErrorHandler } from '../Components/ErrorHandler';
|
|
13
|
-
import { IConnectionManager } from '../
|
|
13
|
+
import { IConnectionManager } from '../Network/IConnectionManager';
|
|
14
14
|
import { IAutoRunnerFactory } from '../Model/IAutoRunner';
|
|
15
15
|
import { ILocalisationService } from '../Localisation/ILocalisationService';
|
|
16
16
|
import { IRouteSecurityService } from '../Routing/IRouteSecurityService';
|
|
@@ -19,6 +19,7 @@ import { INavigationHelper } from '../Routing/INavigationHelper';
|
|
|
19
19
|
import { ILoginErrorHandler } from '../Security/ILoginErrorHandler';
|
|
20
20
|
import { IDecimalService } from "../Numeric";
|
|
21
21
|
import { IServerMessageSubscriber } from "../SignalR/IServerMessageSubscriber";
|
|
22
|
+
import { IAppConnectionMonitor } from "../Network/IAppConnectionMonitor";
|
|
22
23
|
declare const NeoTypes: {
|
|
23
24
|
Axios: ServiceIdentifier<import("axios").AxiosStatic>;
|
|
24
25
|
Config: {
|
|
@@ -27,7 +28,6 @@ declare const NeoTypes: {
|
|
|
27
28
|
};
|
|
28
29
|
Core: {
|
|
29
30
|
AutoRunnerFactory: ServiceIdentifier<IAutoRunnerFactory>;
|
|
30
|
-
/** @deprecated Use Messaging.ConnectionManager */
|
|
31
31
|
ConnectionManager: ServiceIdentifier<IConnectionManager>;
|
|
32
32
|
DecimalService: ServiceIdentifier<IDecimalService<import("../Numeric").IDecimal>>;
|
|
33
33
|
ModelCreator: ServiceIdentifier<IModelCreatorBase>;
|
|
@@ -39,6 +39,10 @@ declare const NeoTypes: {
|
|
|
39
39
|
ConnectionManager: ServiceIdentifier<IConnectionManager>;
|
|
40
40
|
ServerMessageSubscriber: ServiceIdentifier<IServerMessageSubscriber>;
|
|
41
41
|
};
|
|
42
|
+
Network: {
|
|
43
|
+
AppConnectionMonitor: ServiceIdentifier<IAppConnectionMonitor>;
|
|
44
|
+
ConnectionManager: ServiceIdentifier<IConnectionManager>;
|
|
45
|
+
};
|
|
42
46
|
Routing: {
|
|
43
47
|
MenuItemProvider: ServiceIdentifier<IMenuItemProvider<import("../Routing").IMenuRoute>>;
|
|
44
48
|
NavigationHelper: ServiceIdentifier<INavigationHelper>;
|
|
@@ -9,7 +9,6 @@ var NeoTypes = {
|
|
|
9
9
|
},
|
|
10
10
|
Core: {
|
|
11
11
|
AutoRunnerFactory: new ServiceIdentifier("Neo.AutoRunnerFactory"),
|
|
12
|
-
/** @deprecated Use Messaging.ConnectionManager */
|
|
13
12
|
ConnectionManager: connectionManagerType,
|
|
14
13
|
DecimalService: new ServiceIdentifier("Neo.DecimalService"),
|
|
15
14
|
ModelCreator: new ServiceIdentifier("Neo.ModelCreator")
|
|
@@ -21,6 +20,10 @@ var NeoTypes = {
|
|
|
21
20
|
ConnectionManager: connectionManagerType,
|
|
22
21
|
ServerMessageSubscriber: new ServiceIdentifier("Neo.ServerMessageSubscriber"),
|
|
23
22
|
},
|
|
23
|
+
Network: {
|
|
24
|
+
AppConnectionMonitor: new ServiceIdentifier("Neo.AppConnectionMonitor"),
|
|
25
|
+
ConnectionManager: connectionManagerType,
|
|
26
|
+
},
|
|
24
27
|
Routing: {
|
|
25
28
|
MenuItemProvider: new ServiceIdentifier("Neo.MenuItemProvider"),
|
|
26
29
|
NavigationHelper: new ServiceIdentifier("Neo.NavigationHelper"),
|
|
@@ -4,4 +4,4 @@ export { Module } from './Module';
|
|
|
4
4
|
export { default as NeoModule } from './NeoModule';
|
|
5
5
|
export { ServiceIdentifier } from './ServiceIdentifier';
|
|
6
6
|
export { ConfigService } from './Config/ConfigService';
|
|
7
|
-
export { default as ConfigModel, IConfigModel } from './Config/ConfigModel';
|
|
7
|
+
export { default as ConfigModel, IConfigModelData, IConfigModel } from './Config/ConfigModel';
|
|
@@ -3,6 +3,7 @@ import { AsyncDataSource } from './AsyncDataSource';
|
|
|
3
3
|
import NeoModel from '../Model/NeoModel';
|
|
4
4
|
import List from '../Model/List';
|
|
5
5
|
import AxiosUtils from "../AxiosUtils";
|
|
6
|
+
import NetworkUtils from "../Network/NetworkUtils";
|
|
6
7
|
/**
|
|
7
8
|
* Allows an api endpoint to be used directly by a consumer such as a drop down element.
|
|
8
9
|
* If you need the data to be deserialised into a specific lookup model, use ApiClientLookupDataSource.
|
|
@@ -46,7 +47,7 @@ var ConvertingApiClientDataSource = /** @class */ (function (_super) {
|
|
|
46
47
|
return __generator(this, function (_a) {
|
|
47
48
|
switch (_a.label) {
|
|
48
49
|
case 0:
|
|
49
|
-
if (!
|
|
50
|
+
if (!(NetworkUtils.isOnline || !this.supportOffline)) return [3 /*break*/, 2];
|
|
50
51
|
return [4 /*yield*/, AxiosUtils.catchErrors(this.getMethod())];
|
|
51
52
|
case 1:
|
|
52
53
|
result = _a.sent();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IAuthenticationService } from "../Security";
|
|
2
|
+
import { ConnectionState } from "./IConnectionManager";
|
|
3
|
+
import { IAppConnectionMonitor } from "./IAppConnectionMonitor";
|
|
4
|
+
export default abstract class AppConnectionMonitor implements IAppConnectionMonitor {
|
|
5
|
+
protected authenticationService: IAuthenticationService;
|
|
6
|
+
constructor(authenticationService: IAuthenticationService);
|
|
7
|
+
protected reconnectDelayMs: number;
|
|
8
|
+
private state;
|
|
9
|
+
get isOnline(): boolean;
|
|
10
|
+
get requiresSignInRedirect(): boolean;
|
|
11
|
+
get connectionState(): ConnectionState;
|
|
12
|
+
/** Determines if a redirect can be performed to sign the user in. Return false to prevent the redirect. */
|
|
13
|
+
protected abstract beforeSigninRedirect(): Promise<boolean> | boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Called once reconnected, after authenticationService.afterUserLoaded() has completed.
|
|
16
|
+
*/
|
|
17
|
+
protected onReconnected(): Promise<void> | void;
|
|
18
|
+
private updateOnlineStatus;
|
|
19
|
+
private markOffline;
|
|
20
|
+
tryConnect(forceAllowRedirect?: boolean): Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { __awaiter, __decorate, __extends, __generator, __metadata, __param } from "tslib";
|
|
2
|
+
import { Utils } from '../Utils';
|
|
3
|
+
import NeoTypes from '../AppServices/NeoTypes';
|
|
4
|
+
import { inject } from 'inversify';
|
|
5
|
+
import { ConnectionState } from "./IConnectionManager";
|
|
6
|
+
import Globals from "../Globals";
|
|
7
|
+
import ModelBase from "../Model/ModelBase";
|
|
8
|
+
var AppConnectionMonitor = /** @class */ (function () {
|
|
9
|
+
function AppConnectionMonitor(authenticationService) {
|
|
10
|
+
var _this = this;
|
|
11
|
+
this.authenticationService = authenticationService;
|
|
12
|
+
this.reconnectDelayMs = 5000;
|
|
13
|
+
this.updateOnlineStatus = this.updateOnlineStatus.bind(this);
|
|
14
|
+
this.state = new State();
|
|
15
|
+
window.addEventListener("online", this.updateOnlineStatus);
|
|
16
|
+
window.addEventListener("offline", this.updateOnlineStatus);
|
|
17
|
+
var axiosInstance = Globals.appService.get(NeoTypes.Axios);
|
|
18
|
+
axiosInstance.interceptors.response.use(function (response) { return response; }, function (error) {
|
|
19
|
+
// Network error occurred
|
|
20
|
+
if (error.response === undefined && _this.state.connectionState === ConnectionState.Connected) {
|
|
21
|
+
// Server is unreachable but browser thinks we're online
|
|
22
|
+
_this.markOffline();
|
|
23
|
+
}
|
|
24
|
+
return Promise.reject(error);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(AppConnectionMonitor.prototype, "isOnline", {
|
|
28
|
+
get: function () {
|
|
29
|
+
return this.state.connectionState === ConnectionState.Connected;
|
|
30
|
+
},
|
|
31
|
+
enumerable: false,
|
|
32
|
+
configurable: true
|
|
33
|
+
});
|
|
34
|
+
Object.defineProperty(AppConnectionMonitor.prototype, "requiresSignInRedirect", {
|
|
35
|
+
get: function () {
|
|
36
|
+
return this.state.requiresSignInRedirect;
|
|
37
|
+
},
|
|
38
|
+
enumerable: false,
|
|
39
|
+
configurable: true
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(AppConnectionMonitor.prototype, "connectionState", {
|
|
42
|
+
get: function () {
|
|
43
|
+
return this.state.connectionState;
|
|
44
|
+
},
|
|
45
|
+
enumerable: false,
|
|
46
|
+
configurable: true
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Called once reconnected, after authenticationService.afterUserLoaded() has completed.
|
|
50
|
+
*/
|
|
51
|
+
AppConnectionMonitor.prototype.onReconnected = function () {
|
|
52
|
+
};
|
|
53
|
+
AppConnectionMonitor.prototype.updateOnlineStatus = function () {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
55
|
+
var _this = this;
|
|
56
|
+
return __generator(this, function (_a) {
|
|
57
|
+
if (navigator.onLine) {
|
|
58
|
+
Utils.debounce(this, function () { return _this.tryConnect(false); }, this.reconnectDelayMs);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.markOffline();
|
|
62
|
+
}
|
|
63
|
+
return [2 /*return*/];
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
AppConnectionMonitor.prototype.markOffline = function () {
|
|
68
|
+
this.state.connectionState = ConnectionState.Disconnected;
|
|
69
|
+
};
|
|
70
|
+
AppConnectionMonitor.prototype.tryConnect = function () {
|
|
71
|
+
return __awaiter(this, arguments, void 0, function (forceAllowRedirect) {
|
|
72
|
+
var user, _a, canRedirect, _b, e_1;
|
|
73
|
+
if (forceAllowRedirect === void 0) { forceAllowRedirect = false; }
|
|
74
|
+
return __generator(this, function (_c) {
|
|
75
|
+
switch (_c.label) {
|
|
76
|
+
case 0:
|
|
77
|
+
Utils.clearDebounce(this);
|
|
78
|
+
if (this.state.connectionState === ConnectionState.Connected) {
|
|
79
|
+
return [2 /*return*/];
|
|
80
|
+
}
|
|
81
|
+
this.state.connectionState = ConnectionState.ReConnecting;
|
|
82
|
+
_c.label = 1;
|
|
83
|
+
case 1:
|
|
84
|
+
_c.trys.push([1, 13, , 14]);
|
|
85
|
+
if (!this.state.requiresSignInRedirect) return [3 /*break*/, 2];
|
|
86
|
+
_a = null;
|
|
87
|
+
return [3 /*break*/, 4];
|
|
88
|
+
case 2: return [4 /*yield*/, this.authenticationService.signinSilent()];
|
|
89
|
+
case 3:
|
|
90
|
+
_a = _c.sent();
|
|
91
|
+
_c.label = 4;
|
|
92
|
+
case 4:
|
|
93
|
+
user = _a;
|
|
94
|
+
if (!user) return [3 /*break*/, 6];
|
|
95
|
+
this.state.connectionState = ConnectionState.Connected;
|
|
96
|
+
return [4 /*yield*/, this.onReconnected()];
|
|
97
|
+
case 5:
|
|
98
|
+
_c.sent();
|
|
99
|
+
return [3 /*break*/, 12];
|
|
100
|
+
case 6:
|
|
101
|
+
if (!forceAllowRedirect) return [3 /*break*/, 7];
|
|
102
|
+
_b = true;
|
|
103
|
+
return [3 /*break*/, 9];
|
|
104
|
+
case 7: return [4 /*yield*/, this.beforeSigninRedirect()];
|
|
105
|
+
case 8:
|
|
106
|
+
_b = _c.sent();
|
|
107
|
+
_c.label = 9;
|
|
108
|
+
case 9:
|
|
109
|
+
canRedirect = _b;
|
|
110
|
+
if (!canRedirect) return [3 /*break*/, 11];
|
|
111
|
+
return [4 /*yield*/, this.authenticationService.beginSignIn()];
|
|
112
|
+
case 10:
|
|
113
|
+
_c.sent();
|
|
114
|
+
return [2 /*return*/];
|
|
115
|
+
case 11:
|
|
116
|
+
this.state.requiresSignInRedirect = true;
|
|
117
|
+
_c.label = 12;
|
|
118
|
+
case 12: return [3 /*break*/, 14];
|
|
119
|
+
case 13:
|
|
120
|
+
e_1 = _c.sent();
|
|
121
|
+
this.state.connectionState = ConnectionState.Disconnected;
|
|
122
|
+
return [3 /*break*/, 14];
|
|
123
|
+
case 14: return [2 /*return*/];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
AppConnectionMonitor = __decorate([
|
|
129
|
+
__param(0, inject(NeoTypes.Security.AuthenticationService.symbol)),
|
|
130
|
+
__metadata("design:paramtypes", [Object])
|
|
131
|
+
], AppConnectionMonitor);
|
|
132
|
+
return AppConnectionMonitor;
|
|
133
|
+
}());
|
|
134
|
+
export default AppConnectionMonitor;
|
|
135
|
+
var State = /** @class */ (function (_super) {
|
|
136
|
+
__extends(State, _super);
|
|
137
|
+
function State() {
|
|
138
|
+
var _this = _super.call(this) || this;
|
|
139
|
+
_this.connectionState = navigator.onLine ? ConnectionState.Connected : ConnectionState.Disconnected;
|
|
140
|
+
_this.requiresSignInRedirect = false;
|
|
141
|
+
_this.makeObservable();
|
|
142
|
+
return _this;
|
|
143
|
+
}
|
|
144
|
+
return State;
|
|
145
|
+
}(ModelBase));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ConnectionInfo, ConnectionState, ConnectionType, IConnection, IConnectionManager } from "./IConnectionManager";
|
|
2
|
+
export declare class ConnectionManager implements IConnectionManager {
|
|
3
|
+
private _connections;
|
|
4
|
+
registerConnection(connection: IConnection, connectionName: string, connectionType: ConnectionType): void;
|
|
5
|
+
get connectionState(): ConnectionState;
|
|
6
|
+
get connections(): ConnectionInfo[];
|
|
7
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { Computed } from '../Model/Decorators';
|
|
3
|
+
import { injectable } from 'inversify';
|
|
4
|
+
import { ConnectionInfo, ConnectionState } from "./IConnectionManager";
|
|
5
|
+
var ConnectionManager = /** @class */ (function () {
|
|
6
|
+
function ConnectionManager() {
|
|
7
|
+
this._connections = new Map();
|
|
8
|
+
}
|
|
9
|
+
ConnectionManager.prototype.registerConnection = function (connection, connectionName, connectionType) {
|
|
10
|
+
if (!this._connections.has(connectionName)) {
|
|
11
|
+
this._connections.set(connectionName, new ConnectionInfo(connection, connectionName, connectionType));
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(ConnectionManager.prototype, "connectionState", {
|
|
15
|
+
get: function () {
|
|
16
|
+
return this.connections.reduce(function (p, c) { return Math.max(p, c.connection.connectionState); }, ConnectionState.NotStarted);
|
|
17
|
+
},
|
|
18
|
+
enumerable: false,
|
|
19
|
+
configurable: true
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(ConnectionManager.prototype, "connections", {
|
|
22
|
+
get: function () {
|
|
23
|
+
return Array.from(this._connections.values());
|
|
24
|
+
},
|
|
25
|
+
enumerable: false,
|
|
26
|
+
configurable: true
|
|
27
|
+
});
|
|
28
|
+
__decorate([
|
|
29
|
+
Computed(),
|
|
30
|
+
__metadata("design:type", Number),
|
|
31
|
+
__metadata("design:paramtypes", [])
|
|
32
|
+
], ConnectionManager.prototype, "connectionState", null);
|
|
33
|
+
ConnectionManager = __decorate([
|
|
34
|
+
injectable()
|
|
35
|
+
], ConnectionManager);
|
|
36
|
+
return ConnectionManager;
|
|
37
|
+
}());
|
|
38
|
+
export { ConnectionManager };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare enum ConnectionState {
|
|
2
|
+
/** Has not tried to connect yet. */
|
|
3
|
+
NotStarted = 0,
|
|
4
|
+
/** Is connected. */
|
|
5
|
+
Connected = 1,
|
|
6
|
+
/** Is reconnecting after failing to connect, or being disconnected. */
|
|
7
|
+
ReConnecting = 2,
|
|
8
|
+
/** Is disconnected and not trying to reconnect. */
|
|
9
|
+
Disconnected = 3
|
|
10
|
+
}
|
|
11
|
+
export declare enum ConnectionType {
|
|
12
|
+
SignalR = 0
|
|
13
|
+
}
|
|
14
|
+
export interface IConnection {
|
|
15
|
+
readonly connectionState: ConnectionState;
|
|
16
|
+
}
|
|
17
|
+
export declare class ConnectionInfo {
|
|
18
|
+
readonly connection: IConnection;
|
|
19
|
+
readonly connectionName: string;
|
|
20
|
+
readonly connectionType: ConnectionType;
|
|
21
|
+
constructor(connection: IConnection, connectionName: string, connectionType: ConnectionType);
|
|
22
|
+
}
|
|
23
|
+
/** A connection manager is used to display the connection state of multiple connected services to the user. */
|
|
24
|
+
export interface IConnectionManager {
|
|
25
|
+
/**
|
|
26
|
+
* Returns the max state of all the connections.
|
|
27
|
+
*/
|
|
28
|
+
readonly connectionState: ConnectionState;
|
|
29
|
+
/**
|
|
30
|
+
* Gets a list of connections that have been registered.
|
|
31
|
+
*/
|
|
32
|
+
readonly connections: ConnectionInfo[];
|
|
33
|
+
/**
|
|
34
|
+
* Registers a connection to be monitored.
|
|
35
|
+
* @param connection The connection to monitor.
|
|
36
|
+
* @param connectionName The display name of the connection.
|
|
37
|
+
*/
|
|
38
|
+
registerConnection(connection: IConnection, connectionName: string, connectionType: ConnectionType): void;
|
|
39
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export var ConnectionState;
|
|
2
|
+
(function (ConnectionState) {
|
|
3
|
+
/** Has not tried to connect yet. */
|
|
4
|
+
ConnectionState[ConnectionState["NotStarted"] = 0] = "NotStarted";
|
|
5
|
+
/** Is connected. */
|
|
6
|
+
ConnectionState[ConnectionState["Connected"] = 1] = "Connected";
|
|
7
|
+
/** Is reconnecting after failing to connect, or being disconnected. */
|
|
8
|
+
ConnectionState[ConnectionState["ReConnecting"] = 2] = "ReConnecting";
|
|
9
|
+
/** Is disconnected and not trying to reconnect. */
|
|
10
|
+
ConnectionState[ConnectionState["Disconnected"] = 3] = "Disconnected";
|
|
11
|
+
})(ConnectionState || (ConnectionState = {}));
|
|
12
|
+
export var ConnectionType;
|
|
13
|
+
(function (ConnectionType) {
|
|
14
|
+
ConnectionType[ConnectionType["SignalR"] = 0] = "SignalR";
|
|
15
|
+
})(ConnectionType || (ConnectionType = {}));
|
|
16
|
+
var ConnectionInfo = /** @class */ (function () {
|
|
17
|
+
function ConnectionInfo(connection, connectionName, connectionType) {
|
|
18
|
+
this.connection = connection;
|
|
19
|
+
this.connectionName = connectionName;
|
|
20
|
+
this.connectionType = connectionType;
|
|
21
|
+
}
|
|
22
|
+
return ConnectionInfo;
|
|
23
|
+
}());
|
|
24
|
+
export { ConnectionInfo };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IConfigModel } from "../AppServices";
|
|
2
|
+
export default class NetworkUtils {
|
|
3
|
+
private static _monitorInstance?;
|
|
4
|
+
/**
|
|
5
|
+
* Indicates whether the app is online and ready to send requests to the server.
|
|
6
|
+
* Even if `navigator.onLine` reports true, the app may not have re-authenticated after a connection loss.
|
|
7
|
+
*/
|
|
8
|
+
static get isOnline(): boolean;
|
|
9
|
+
static canFetch(config: IConfigModel): boolean;
|
|
10
|
+
static useCachedData(config: IConfigModel): boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Globals from "../Globals";
|
|
2
|
+
import NeoTypes from "../AppServices/NeoTypes";
|
|
3
|
+
var NetworkUtils = /** @class */ (function () {
|
|
4
|
+
function NetworkUtils() {
|
|
5
|
+
}
|
|
6
|
+
Object.defineProperty(NetworkUtils, "isOnline", {
|
|
7
|
+
/**
|
|
8
|
+
* Indicates whether the app is online and ready to send requests to the server.
|
|
9
|
+
* Even if `navigator.onLine` reports true, the app may not have re-authenticated after a connection loss.
|
|
10
|
+
*/
|
|
11
|
+
get: function () {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
if (this._monitorInstance === undefined) {
|
|
14
|
+
this._monitorInstance = Globals.appService.tryGet(NeoTypes.Network.AppConnectionMonitor);
|
|
15
|
+
}
|
|
16
|
+
return (_b = (_a = this._monitorInstance) === null || _a === void 0 ? void 0 : _a.isOnline) !== null && _b !== void 0 ? _b : navigator.onLine;
|
|
17
|
+
},
|
|
18
|
+
enumerable: false,
|
|
19
|
+
configurable: true
|
|
20
|
+
});
|
|
21
|
+
NetworkUtils.canFetch = function (config) {
|
|
22
|
+
return !config.supportsOffline || this.isOnline;
|
|
23
|
+
};
|
|
24
|
+
NetworkUtils.useCachedData = function (config) {
|
|
25
|
+
return config.supportsOffline && !this.isOnline;
|
|
26
|
+
};
|
|
27
|
+
return NetworkUtils;
|
|
28
|
+
}());
|
|
29
|
+
export default NetworkUtils;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ConnectionInfo, ConnectionState, ConnectionType, IConnection, IConnectionManager } from "./IConnectionManager";
|
|
2
|
+
import AppConnectionMonitor from "./AppConnectionMonitor";
|
|
3
|
+
import NetworkUtils from "./NetworkUtils";
|
|
4
|
+
import { ConnectionManager } from "./ConnectionManager";
|
|
5
|
+
export { ConnectionInfo, ConnectionState, ConnectionType, IConnection, IConnectionManager, ConnectionManager, AppConnectionMonitor, NetworkUtils as Utils };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ConnectionInfo, ConnectionState, ConnectionType } from "./IConnectionManager";
|
|
2
|
+
import AppConnectionMonitor from "./AppConnectionMonitor";
|
|
3
|
+
import NetworkUtils from "./NetworkUtils";
|
|
4
|
+
import { ConnectionManager } from "./ConnectionManager";
|
|
5
|
+
export { ConnectionInfo, ConnectionState, ConnectionType, ConnectionManager, AppConnectionMonitor, NetworkUtils as Utils };
|
|
@@ -3,16 +3,18 @@ import { ISignInResult } from './SignInResult';
|
|
|
3
3
|
export default interface IAuthenticationService {
|
|
4
4
|
/**
|
|
5
5
|
* Load a user from session storage if there is a stored token.
|
|
6
|
+
* Will also try perform a silent sign in if opened from another window.
|
|
6
7
|
*/
|
|
7
8
|
loadUserFromSession(): Promise<IUser | null>;
|
|
8
9
|
/**
|
|
9
10
|
* Checks if the user is signed in, and if not, redirects to login.
|
|
10
11
|
* Returns true if the user is logged in.
|
|
12
|
+
* @param redirectLocal Redirect path. If this is not supplied, the current path will be used.
|
|
11
13
|
*/
|
|
12
14
|
ensureSignedIn(redirectLocal?: string): boolean;
|
|
13
15
|
/**
|
|
14
16
|
* Starts the sign in process
|
|
15
|
-
* @param redirectLocal The path to redirect to after calling endSignIn
|
|
17
|
+
* @param redirectLocal The path to redirect to after calling endSignIn. If this is not supplied, the current path will be used.
|
|
16
18
|
*/
|
|
17
19
|
beginSignIn(redirectLocal?: string): Promise<any>;
|
|
18
20
|
/**
|
|
@@ -24,7 +26,7 @@ export default interface IAuthenticationService {
|
|
|
24
26
|
* Result.success will be false if an error occurs. Errors will be handled by the service bound to NeoTypes.Security.LoginErrorHandler.
|
|
25
27
|
*/
|
|
26
28
|
tryCompleteSignIn(): Promise<ISignInResult>;
|
|
27
|
-
signinSilent(): Promise<
|
|
29
|
+
signinSilent(): Promise<IUser | null>;
|
|
28
30
|
endSignInSilent(): Promise<any>;
|
|
29
31
|
beginSignOut(): void;
|
|
30
32
|
endSignOut(): Promise<any>;
|
|
@@ -10,6 +10,7 @@ import { SignInResult } from '../SignInResult';
|
|
|
10
10
|
export default abstract class OidcAuthService<TUser extends OidcUser = OidcUser> implements IAuthenticationService {
|
|
11
11
|
protected userManager: IUserManager;
|
|
12
12
|
private axios;
|
|
13
|
+
private config;
|
|
13
14
|
private _user;
|
|
14
15
|
private isRedirecting;
|
|
15
16
|
private afterUserLoadedPromise;
|
|
@@ -18,15 +19,10 @@ export default abstract class OidcAuthService<TUser extends OidcUser = OidcUser>
|
|
|
18
19
|
* @param userManager Oidc-client user manager instance
|
|
19
20
|
* @param user User which existed in storage at startup
|
|
20
21
|
*/
|
|
21
|
-
constructor(userManager: IUserManager, axios: AxiosInstance);
|
|
22
|
+
constructor(userManager: IUserManager, axios: AxiosInstance, config?: import("../../AppServices").IConfigModel);
|
|
22
23
|
isSigningOut: boolean;
|
|
23
|
-
loadUserFromToken(): Promise<TUser | null>;
|
|
24
24
|
loadUserFromSession(): Promise<TUser | null>;
|
|
25
25
|
ensureSignedIn(redirectLocal?: string): boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Redirect to identity server to get the auth token.
|
|
28
|
-
* @param redirectPath Local path to redirect to once login is complete.
|
|
29
|
-
*/
|
|
30
26
|
beginSignIn(redirectPath?: string): Promise<any>;
|
|
31
27
|
/**
|
|
32
28
|
* Reads the access token from the query string and returns the redirect path.
|
|
@@ -38,13 +34,14 @@ export default abstract class OidcAuthService<TUser extends OidcUser = OidcUser>
|
|
|
38
34
|
*/
|
|
39
35
|
tryCompleteSignIn(): Promise<SignInResult>;
|
|
40
36
|
endSignInSilent(): Promise<any>;
|
|
37
|
+
protected setUserDataAsync(userData: IOidcUser): Promise<void>;
|
|
41
38
|
private onUserLoaded;
|
|
42
39
|
protected afterUserLoaded(): Promise<void> | void;
|
|
43
|
-
private
|
|
40
|
+
private awaitAfterUserLoadedAsync;
|
|
44
41
|
protected createUser(user: IOidcUser): OidcUser;
|
|
45
42
|
private onUserUnloaded;
|
|
46
43
|
private setUser;
|
|
47
|
-
signinSilent(): Promise<
|
|
44
|
+
signinSilent(): Promise<TUser | null>;
|
|
48
45
|
beginSignOut(): void;
|
|
49
46
|
endSignOut(): Promise<any>;
|
|
50
47
|
private signOutLocal;
|
|
@@ -4,6 +4,8 @@ import OidcUser from './OidcUser';
|
|
|
4
4
|
import { SignInResult } from '../SignInResult';
|
|
5
5
|
import { Misc } from '../../';
|
|
6
6
|
import { NeoTypes } from '../../AppServices';
|
|
7
|
+
import NetworkUtils from "../../Network/NetworkUtils";
|
|
8
|
+
var storageKey = "neo-app-user-data";
|
|
7
9
|
/**
|
|
8
10
|
* Oidc authentication service base class.
|
|
9
11
|
* You must override this class and provide the user manager implementation from the oidc library.
|
|
@@ -14,9 +16,12 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
14
16
|
* @param userManager Oidc-client user manager instance
|
|
15
17
|
* @param user User which existed in storage at startup
|
|
16
18
|
*/
|
|
17
|
-
function OidcAuthService(userManager, axios) {
|
|
19
|
+
function OidcAuthService(userManager, axios, config) {
|
|
20
|
+
if (config === void 0) { config = Misc.Globals.appService.get(NeoTypes.Config.ConfigModel); }
|
|
21
|
+
var _this = this;
|
|
18
22
|
this.userManager = userManager;
|
|
19
23
|
this.axios = axios;
|
|
24
|
+
this.config = config;
|
|
20
25
|
this._user = null;
|
|
21
26
|
this.isRedirecting = false;
|
|
22
27
|
this.isSigningOut = false;
|
|
@@ -25,28 +30,38 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
25
30
|
this.userManager.events.addUserUnloaded(this.onUserUnloaded.bind(this));
|
|
26
31
|
if (!this.userManager.settings.automaticSilentRenew) {
|
|
27
32
|
// If automaticSilentRenew is set to true, then the user manager will handle automatic renewal.
|
|
28
|
-
this.userManager.events.addAccessTokenExpiring(
|
|
33
|
+
this.userManager.events.addAccessTokenExpiring(function () { return _this.userManager.signinSilent(); });
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
|
-
OidcAuthService.prototype.loadUserFromToken = function () {
|
|
32
|
-
return this.loadUserFromSession();
|
|
33
|
-
};
|
|
34
36
|
OidcAuthService.prototype.loadUserFromSession = function () {
|
|
35
37
|
return __awaiter(this, void 0, void 0, function () {
|
|
36
|
-
var user;
|
|
38
|
+
var userData, user;
|
|
37
39
|
return __generator(this, function (_a) {
|
|
38
40
|
switch (_a.label) {
|
|
39
|
-
case 0:
|
|
41
|
+
case 0:
|
|
42
|
+
if (!NetworkUtils.useCachedData(this.config)) return [3 /*break*/, 3];
|
|
43
|
+
userData = localStorage.getItem(storageKey);
|
|
44
|
+
if (!userData) return [3 /*break*/, 2];
|
|
45
|
+
return [4 /*yield*/, this.setUserDataAsync(JSON.parse(userData))];
|
|
40
46
|
case 1:
|
|
47
|
+
_a.sent();
|
|
48
|
+
_a.label = 2;
|
|
49
|
+
case 2: return [2 /*return*/, this.user];
|
|
50
|
+
case 3: return [4 /*yield*/, this.userManager.getUser()];
|
|
51
|
+
case 4:
|
|
41
52
|
user = _a.sent();
|
|
42
|
-
if (!(user && !user.expired)) return [3 /*break*/,
|
|
53
|
+
if (!(user && !user.expired)) return [3 /*break*/, 6];
|
|
54
|
+
// Get user does not raise the onUserLoaded event, so we call it manually.
|
|
55
|
+
return [4 /*yield*/, this.setUserDataAsync(user)];
|
|
56
|
+
case 5:
|
|
43
57
|
// Get user does not raise the onUserLoaded event, so we call it manually.
|
|
44
|
-
this.onUserLoaded(user);
|
|
45
|
-
return [4 /*yield*/, this.completeAfterUserLoaded()];
|
|
46
|
-
case 2:
|
|
47
58
|
_a.sent();
|
|
48
|
-
|
|
49
|
-
case
|
|
59
|
+
return [2 /*return*/, this.user];
|
|
60
|
+
case 6:
|
|
61
|
+
if (!!!window.opener) return [3 /*break*/, 8];
|
|
62
|
+
return [4 /*yield*/, this.signinSilent()];
|
|
63
|
+
case 7: return [2 /*return*/, _a.sent()];
|
|
64
|
+
case 8: return [2 /*return*/, null];
|
|
50
65
|
}
|
|
51
66
|
});
|
|
52
67
|
});
|
|
@@ -61,11 +76,10 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
61
76
|
}
|
|
62
77
|
return true;
|
|
63
78
|
};
|
|
64
|
-
/**
|
|
65
|
-
* Redirect to identity server to get the auth token.
|
|
66
|
-
* @param redirectPath Local path to redirect to once login is complete.
|
|
67
|
-
*/
|
|
68
79
|
OidcAuthService.prototype.beginSignIn = function (redirectPath) {
|
|
80
|
+
if (redirectPath === undefined) {
|
|
81
|
+
redirectPath = (window.location.pathname + window.location.search).substring(this.config.baseUrl.length);
|
|
82
|
+
}
|
|
69
83
|
if (!this.isRedirecting) {
|
|
70
84
|
this.isRedirecting = true;
|
|
71
85
|
return this.userManager.signinRedirect({ state: redirectPath });
|
|
@@ -118,7 +132,7 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
118
132
|
return [4 /*yield*/, this.endSignIn()];
|
|
119
133
|
case 2:
|
|
120
134
|
redirectPath = _a.sent();
|
|
121
|
-
return [4 /*yield*/, this.
|
|
135
|
+
return [4 /*yield*/, this.awaitAfterUserLoadedAsync()];
|
|
122
136
|
case 3:
|
|
123
137
|
_a.sent();
|
|
124
138
|
return [2 /*return*/, new SignInResult(true, redirectPath)];
|
|
@@ -134,13 +148,31 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
134
148
|
OidcAuthService.prototype.endSignInSilent = function () {
|
|
135
149
|
return this.userManager.signinSilentCallback();
|
|
136
150
|
};
|
|
137
|
-
OidcAuthService.prototype.
|
|
138
|
-
|
|
151
|
+
OidcAuthService.prototype.setUserDataAsync = function (userData) {
|
|
152
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
153
|
+
return __generator(this, function (_a) {
|
|
154
|
+
switch (_a.label) {
|
|
155
|
+
case 0:
|
|
156
|
+
this.onUserLoaded(userData, false);
|
|
157
|
+
return [4 /*yield*/, this.awaitAfterUserLoadedAsync()];
|
|
158
|
+
case 1:
|
|
159
|
+
_a.sent();
|
|
160
|
+
return [2 /*return*/];
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
OidcAuthService.prototype.onUserLoaded = function (userData, store) {
|
|
166
|
+
if (store === void 0) { store = true; }
|
|
167
|
+
this.setUser(this.createUser(userData));
|
|
168
|
+
if (store && this.config.supportsOffline) {
|
|
169
|
+
localStorage.setItem(storageKey, JSON.stringify(userData));
|
|
170
|
+
}
|
|
139
171
|
this.afterUserLoadedPromise = this.afterUserLoaded();
|
|
140
172
|
};
|
|
141
173
|
OidcAuthService.prototype.afterUserLoaded = function () {
|
|
142
174
|
};
|
|
143
|
-
OidcAuthService.prototype.
|
|
175
|
+
OidcAuthService.prototype.awaitAfterUserLoadedAsync = function () {
|
|
144
176
|
return __awaiter(this, void 0, void 0, function () {
|
|
145
177
|
return __generator(this, function (_a) {
|
|
146
178
|
switch (_a.label) {
|
|
@@ -172,7 +204,29 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
172
204
|
this._user = user;
|
|
173
205
|
};
|
|
174
206
|
OidcAuthService.prototype.signinSilent = function () {
|
|
175
|
-
return this
|
|
207
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
208
|
+
var e_3;
|
|
209
|
+
return __generator(this, function (_a) {
|
|
210
|
+
switch (_a.label) {
|
|
211
|
+
case 0:
|
|
212
|
+
_a.trys.push([0, 2, , 3]);
|
|
213
|
+
return [4 /*yield*/, this.userManager.signinSilent()];
|
|
214
|
+
case 1:
|
|
215
|
+
_a.sent();
|
|
216
|
+
return [3 /*break*/, 3];
|
|
217
|
+
case 2:
|
|
218
|
+
e_3 = _a.sent();
|
|
219
|
+
if (e_3.error === "login_required" || e_3.error === "consent_required" || e_3.error === "interaction_required") {
|
|
220
|
+
return [2 /*return*/, null];
|
|
221
|
+
}
|
|
222
|
+
return [3 /*break*/, 3];
|
|
223
|
+
case 3: return [4 /*yield*/, this.awaitAfterUserLoadedAsync()];
|
|
224
|
+
case 4:
|
|
225
|
+
_a.sent();
|
|
226
|
+
return [2 /*return*/, this.user];
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
});
|
|
176
230
|
};
|
|
177
231
|
OidcAuthService.prototype.beginSignOut = function () {
|
|
178
232
|
if (!this.isRedirecting) {
|
|
@@ -204,6 +258,10 @@ var OidcAuthService = /** @class */ (function () {
|
|
|
204
258
|
});
|
|
205
259
|
Object.defineProperty(OidcAuthService.prototype, "isAuthenticated", {
|
|
206
260
|
get: function () {
|
|
261
|
+
if (NetworkUtils.useCachedData(this.config)) {
|
|
262
|
+
// Ignore expiry when offline.
|
|
263
|
+
return this._user !== null;
|
|
264
|
+
}
|
|
207
265
|
return this.user !== null && !this.user.hasExpired;
|
|
208
266
|
},
|
|
209
267
|
enumerable: false,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as signalR from '@microsoft/signalr';
|
|
2
2
|
import { IHubReceiver } from "./HubReceiver";
|
|
3
3
|
import { AppServices } from '../';
|
|
4
|
-
import { IConnection, ConnectionState } from '../
|
|
4
|
+
import { IConnection, ConnectionState } from '../Network/IConnectionManager';
|
|
5
5
|
import { IDisposable } from '../Misc';
|
|
6
6
|
export interface IHubBase extends IConnection, IDisposable {
|
|
7
7
|
/**
|
package/dist/SignalR/HubBase.js
CHANGED
|
@@ -2,7 +2,7 @@ import { __awaiter, __generator, __spreadArray } from "tslib";
|
|
|
2
2
|
import * as signalR from '@microsoft/signalr';
|
|
3
3
|
import HubReceiver from "./HubReceiver";
|
|
4
4
|
import { AppServices, Misc, TaskRunner } from '../';
|
|
5
|
-
import { ConnectionState } from '../
|
|
5
|
+
import { ConnectionState } from '../Network/IConnectionManager';
|
|
6
6
|
import { ObservableValue } from '../Model';
|
|
7
7
|
import { Utils } from '../Utils';
|
|
8
8
|
var HubBase = /** @class */ (function () {
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ import * as JsonSchema from './JsonSchema';
|
|
|
23
23
|
import * as Localisation from './Localisation';
|
|
24
24
|
import * as Misc from './Misc';
|
|
25
25
|
import * as Model from './Model';
|
|
26
|
-
import * as Network from './
|
|
26
|
+
import * as Network from './Network';
|
|
27
27
|
import * as Numeric from './Numeric';
|
|
28
28
|
import * as Routing from './Routing';
|
|
29
29
|
import * as Security from './Security';
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import * as JsonSchema from './JsonSchema';
|
|
|
26
26
|
import * as Localisation from './Localisation';
|
|
27
27
|
import * as Misc from './Misc';
|
|
28
28
|
import * as Model from './Model';
|
|
29
|
-
import * as Network from './
|
|
29
|
+
import * as Network from './Network';
|
|
30
30
|
import * as Numeric from './Numeric';
|
|
31
31
|
import * as Routing from './Routing';
|
|
32
32
|
import * as Security from './Security';
|