@openremote/core 1.0.3 → 1.2.0-snapshot.20240512154942
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 → lib}/asset-mixin.d.ts +2 -0
- package/lib/asset-mixin.js +1 -0
- package/lib/asset-mixin.js.map +1 -0
- package/{dist → lib}/console.d.ts +14 -5
- package/lib/console.js +1 -0
- package/lib/console.js.map +1 -0
- package/lib/defaults.js +1 -0
- package/lib/defaults.js.map +1 -0
- package/{dist → lib}/event.d.ts +20 -19
- package/lib/event.js +1 -0
- package/lib/event.js.map +1 -0
- package/lib/index.d.ts +150 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/util.d.ts +92 -0
- package/lib/util.js +1 -0
- package/lib/util.js.map +1 -0
- package/package.json +24 -25
- package/.project +0 -17
- package/.settings/org.eclipse.buildship.core.prefs +0 -2
- package/@types/i18next-sprintf-postprocessor.d.ts +0 -1
- package/dist/asset-mixin.js +0 -156
- package/dist/console.js +0 -452
- package/dist/defaults.js +0 -16
- package/dist/event.js +0 -567
- package/dist/index.d.ts +0 -224
- package/dist/index.js +0 -996
- package/dist/mdi-icons.json +0 -1
- package/dist/or-icon-set.d.ts +0 -3
- package/dist/or-icon-set.js +0 -10
- package/dist/umd/index.bundle.js +0 -273
- package/dist/umd/index.js +0 -7
- package/dist/umd/index.orbundle.js +0 -280
- package/dist/util.d.ts +0 -41
- package/dist/util.js +0 -362
- package/mdi-iconset-generator.js +0 -34
- package/tsconfig.json +0 -16
- package/typedoc.js +0 -3
- package/webpack.config.js +0 -16
- /package/{dist → lib}/defaults.d.ts +0 -0
package/dist/index.js
DELETED
|
@@ -1,996 +0,0 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
import "url-search-params-polyfill";
|
|
11
|
-
import { Console } from "./console";
|
|
12
|
-
import rest from "@openremote/rest";
|
|
13
|
-
import { EventProviderStatus, WebSocketEventProvider } from "./event";
|
|
14
|
-
import i18next from "i18next";
|
|
15
|
-
import i18nextXhr from "i18next-xhr-backend";
|
|
16
|
-
import sprintf from 'i18next-sprintf-postprocessor';
|
|
17
|
-
import moment from "moment";
|
|
18
|
-
import * as Util from "./util";
|
|
19
|
-
import orIconSet from "./or-icon-set";
|
|
20
|
-
// Re-exports
|
|
21
|
-
export { Util };
|
|
22
|
-
export * from "./asset-mixin";
|
|
23
|
-
export * from "./console";
|
|
24
|
-
export * from "./event";
|
|
25
|
-
export * from "./defaults";
|
|
26
|
-
export const DEFAULT_ICONSET = "mdi";
|
|
27
|
-
export var ORError;
|
|
28
|
-
(function (ORError) {
|
|
29
|
-
ORError["MANAGER_FAILED_TO_LOAD"] = "MANAGER_FAILED_TO_LOAD";
|
|
30
|
-
ORError["AUTH_FAILED"] = "AUTH_FAILED";
|
|
31
|
-
ORError["AUTH_TYPE_UNSUPPORTED"] = "AUTH_TYPE_UNSUPPORTED";
|
|
32
|
-
ORError["CONSOLE_ERROR"] = "CONSOLE_INIT_ERROR";
|
|
33
|
-
ORError["EVENTS_CONNECTION_ERROR"] = "EVENTS_CONNECTION_ERROR";
|
|
34
|
-
ORError["TRANSLATION_ERROR"] = "TRANSLATION_ERROR";
|
|
35
|
-
})(ORError || (ORError = {}));
|
|
36
|
-
export var Auth;
|
|
37
|
-
(function (Auth) {
|
|
38
|
-
Auth["KEYCLOAK"] = "KEYCLOAK";
|
|
39
|
-
Auth["BASIC"] = "BASIC";
|
|
40
|
-
Auth["NONE"] = "NONE";
|
|
41
|
-
})(Auth || (Auth = {}));
|
|
42
|
-
export var OREvent;
|
|
43
|
-
(function (OREvent) {
|
|
44
|
-
OREvent["ERROR"] = "ERROR";
|
|
45
|
-
OREvent["READY"] = "READY";
|
|
46
|
-
OREvent["CONSOLE_INIT"] = "CONSOLE_INIT";
|
|
47
|
-
OREvent["CONSOLE_READY"] = "CONSOLE_READY";
|
|
48
|
-
OREvent["EVENTS_CONNECTED"] = "EVENTS_CONNECTED";
|
|
49
|
-
OREvent["EVENTS_CONNECTING"] = "EVENTS_CONNECTING";
|
|
50
|
-
OREvent["EVENTS_DISCONNECTED"] = "EVENTS_DISCONNECTED";
|
|
51
|
-
OREvent["TRANSLATE_INIT"] = "TRANSLATE_INIT";
|
|
52
|
-
OREvent["TRANSLATE_LANGUAGE_CHANGED"] = "TRANSLATE_LANGUAGE_CHANGED";
|
|
53
|
-
OREvent["DISPLAY_REALM_CHANGED"] = "DISPLAY_REALM_CHANGED";
|
|
54
|
-
})(OREvent || (OREvent = {}));
|
|
55
|
-
export var EventProviderType;
|
|
56
|
-
(function (EventProviderType) {
|
|
57
|
-
EventProviderType["WEBSOCKET"] = "WEBSOCKET";
|
|
58
|
-
EventProviderType["POLLING"] = "POLLING";
|
|
59
|
-
})(EventProviderType || (EventProviderType = {}));
|
|
60
|
-
export var MapType;
|
|
61
|
-
(function (MapType) {
|
|
62
|
-
MapType["VECTOR"] = "VECTOR";
|
|
63
|
-
MapType["RASTER"] = "RASTER";
|
|
64
|
-
})(MapType || (MapType = {}));
|
|
65
|
-
export class IconSetAddedEvent extends CustomEvent {
|
|
66
|
-
constructor() {
|
|
67
|
-
super(IconSetAddedEvent.NAME, {
|
|
68
|
-
bubbles: true,
|
|
69
|
-
composed: true
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
IconSetAddedEvent.NAME = "or-iconset-added";
|
|
74
|
-
export class ORIconSets {
|
|
75
|
-
constructor() {
|
|
76
|
-
this._icons = {};
|
|
77
|
-
}
|
|
78
|
-
addIconSet(name, iconset) {
|
|
79
|
-
this._icons[name] = iconset;
|
|
80
|
-
window.dispatchEvent(new IconSetAddedEvent());
|
|
81
|
-
}
|
|
82
|
-
getIconSet(name) {
|
|
83
|
-
return this._icons[name];
|
|
84
|
-
}
|
|
85
|
-
getIcon(icon) {
|
|
86
|
-
if (!icon) {
|
|
87
|
-
return undefined;
|
|
88
|
-
}
|
|
89
|
-
let parts = (icon || "").split(":");
|
|
90
|
-
let iconName = parts.pop();
|
|
91
|
-
let iconSetName = parts.pop() || DEFAULT_ICONSET;
|
|
92
|
-
if (!iconSetName || iconSetName === "" || !iconName || iconName === "") {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
let iconSet = IconSets.getIconSet(iconSetName);
|
|
96
|
-
//iconName = iconName.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
|
|
97
|
-
if (!iconSet || !iconSet.icons.hasOwnProperty(iconName)) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
const iconData = iconSet.icons[iconName];
|
|
101
|
-
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
102
|
-
svg.setAttribute("viewBox", "0 0 " + iconSet.size + " " + iconSet.size);
|
|
103
|
-
svg.style.cssText = "pointer-events: none; display: block; width: 100%; height: 100%;";
|
|
104
|
-
svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
|
105
|
-
svg.setAttribute("focusable", "false");
|
|
106
|
-
if (iconData.startsWith("<")) {
|
|
107
|
-
svg.innerHTML = iconData;
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
111
|
-
path.setAttribute("d", iconData);
|
|
112
|
-
path.style.pointerEvents = "pointer-events: var(--or-icon-pointer-events, none);";
|
|
113
|
-
svg.appendChild(path);
|
|
114
|
-
}
|
|
115
|
-
return svg;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
export class AssetModelUtil {
|
|
119
|
-
static getAssetDescriptors() {
|
|
120
|
-
return [...this._assetDescriptors];
|
|
121
|
-
}
|
|
122
|
-
static getAttributeDescriptors() {
|
|
123
|
-
return [...this._attributeDescriptors];
|
|
124
|
-
}
|
|
125
|
-
static getAttributeValueDescriptors() {
|
|
126
|
-
return [...this._attributeValueDescriptors];
|
|
127
|
-
}
|
|
128
|
-
static getMetaItemDescriptors() {
|
|
129
|
-
return [...this._metaItemDescriptors];
|
|
130
|
-
}
|
|
131
|
-
static getAssetDescriptor(type) {
|
|
132
|
-
if (!type) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
return this._assetDescriptors.find((assetDescriptor) => {
|
|
136
|
-
return assetDescriptor.type === type;
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
static getAttributeDescriptor(attributeName, assetTypeOrDescriptor) {
|
|
140
|
-
if (!attributeName) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
let descriptor = this._attributeDescriptors.find((attributeDescriptor) => {
|
|
144
|
-
return attributeDescriptor.attributeName === attributeName;
|
|
145
|
-
});
|
|
146
|
-
if (descriptor || !assetTypeOrDescriptor) {
|
|
147
|
-
return descriptor;
|
|
148
|
-
}
|
|
149
|
-
let assetDescriptor;
|
|
150
|
-
if (assetTypeOrDescriptor.name) {
|
|
151
|
-
assetDescriptor = assetTypeOrDescriptor;
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
assetDescriptor = this.getAssetDescriptor(assetTypeOrDescriptor);
|
|
155
|
-
}
|
|
156
|
-
if (assetDescriptor && assetDescriptor.attributeDescriptors) {
|
|
157
|
-
descriptor = assetDescriptor.attributeDescriptors.find((ad) => ad.attributeName === attributeName);
|
|
158
|
-
}
|
|
159
|
-
return descriptor;
|
|
160
|
-
}
|
|
161
|
-
static getAttributeValueDescriptor(name, attributeNameOrDescriptor, assetTypeOrDescriptor) {
|
|
162
|
-
if (!name) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
const descriptor = this._attributeValueDescriptors.find((attributeValueDescriptor) => {
|
|
166
|
-
return attributeValueDescriptor.name === name;
|
|
167
|
-
});
|
|
168
|
-
if (descriptor || !attributeNameOrDescriptor) {
|
|
169
|
-
return descriptor;
|
|
170
|
-
}
|
|
171
|
-
let attributeDescriptor;
|
|
172
|
-
if (attributeNameOrDescriptor.attributeName) {
|
|
173
|
-
attributeDescriptor = attributeNameOrDescriptor;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
attributeDescriptor = this.getAttributeDescriptor(attributeNameOrDescriptor, assetTypeOrDescriptor);
|
|
177
|
-
}
|
|
178
|
-
if (attributeDescriptor) {
|
|
179
|
-
return attributeDescriptor.valueDescriptor;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
static getAttributeAndValueDescriptors(assetType, attributeOrNameOrDescriptor) {
|
|
183
|
-
let attributeDescriptor;
|
|
184
|
-
let attributeValueDescriptor;
|
|
185
|
-
let attributeName;
|
|
186
|
-
let attributeTypeOrDescriptor;
|
|
187
|
-
if (typeof attributeOrNameOrDescriptor === "string") {
|
|
188
|
-
attributeName = attributeOrNameOrDescriptor;
|
|
189
|
-
attributeDescriptor = AssetModelUtil.getAttributeDescriptor(attributeOrNameOrDescriptor, assetType);
|
|
190
|
-
attributeTypeOrDescriptor = attributeDescriptor ? attributeDescriptor.valueDescriptor : undefined;
|
|
191
|
-
}
|
|
192
|
-
else if (attributeOrNameOrDescriptor) {
|
|
193
|
-
if (attributeOrNameOrDescriptor.type) {
|
|
194
|
-
attributeName = attributeOrNameOrDescriptor.name;
|
|
195
|
-
attributeDescriptor = AssetModelUtil.getAttributeDescriptor(attributeName, assetType);
|
|
196
|
-
attributeTypeOrDescriptor = attributeOrNameOrDescriptor.type;
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
attributeName = attributeOrNameOrDescriptor.attributeName;
|
|
200
|
-
attributeDescriptor = attributeOrNameOrDescriptor;
|
|
201
|
-
attributeTypeOrDescriptor = attributeOrNameOrDescriptor.valueDescriptor;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
if (attributeTypeOrDescriptor) {
|
|
205
|
-
if (typeof attributeTypeOrDescriptor === "string") {
|
|
206
|
-
attributeValueDescriptor = AssetModelUtil.getAttributeValueDescriptor(attributeTypeOrDescriptor, assetType, attributeName);
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
attributeValueDescriptor = attributeTypeOrDescriptor;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return [attributeDescriptor, attributeValueDescriptor];
|
|
213
|
-
}
|
|
214
|
-
static getMetaItemDescriptor(urn, attributeNameOrDescriptor, assetTypeOrDescriptor) {
|
|
215
|
-
if (!urn) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
let descriptor = this._metaItemDescriptors.find((metaItemDescriptor) => {
|
|
219
|
-
return metaItemDescriptor.urn === urn;
|
|
220
|
-
});
|
|
221
|
-
if (descriptor || !attributeNameOrDescriptor) {
|
|
222
|
-
return descriptor;
|
|
223
|
-
}
|
|
224
|
-
let attributeDescriptor;
|
|
225
|
-
if (attributeNameOrDescriptor.attributeName) {
|
|
226
|
-
attributeDescriptor = attributeNameOrDescriptor;
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
attributeDescriptor = this.getAttributeDescriptor(attributeNameOrDescriptor, assetTypeOrDescriptor);
|
|
230
|
-
}
|
|
231
|
-
if (attributeDescriptor && attributeDescriptor.metaItemDescriptors) {
|
|
232
|
-
descriptor = attributeDescriptor.metaItemDescriptors.find((mid) => mid.urn === urn);
|
|
233
|
-
}
|
|
234
|
-
return descriptor;
|
|
235
|
-
}
|
|
236
|
-
static attributeValueDescriptorsMatch(attributeValueDescriptor1, attributeValueDescriptor2) {
|
|
237
|
-
if (attributeValueDescriptor1 === attributeValueDescriptor2) {
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
if (!attributeValueDescriptor1 || !attributeValueDescriptor2) {
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
return attributeValueDescriptor1.name === attributeValueDescriptor2.name && attributeValueDescriptor1.valueType === attributeValueDescriptor2.valueType;
|
|
244
|
-
}
|
|
245
|
-
static getMetaInitialValueFromMetaDescriptors(metaItemUrn, metaItemDescriptors) {
|
|
246
|
-
if (!metaItemDescriptors) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
const matchUrn = typeof metaItemUrn === "string" ? metaItemUrn : metaItemUrn.urn;
|
|
250
|
-
const metaItemDescriptor = metaItemDescriptors && metaItemDescriptors.find((mid) => mid && mid.urn === matchUrn);
|
|
251
|
-
if (metaItemDescriptor) {
|
|
252
|
-
return metaItemDescriptor.initialValue;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
static getMetaItemDescriptorInitialValue(metaItemDescriptor, initialValue) {
|
|
256
|
-
if (metaItemDescriptor.valueFixed) {
|
|
257
|
-
return metaItemDescriptor;
|
|
258
|
-
}
|
|
259
|
-
const newMetaItem = JSON.parse(JSON.stringify(metaItemDescriptor));
|
|
260
|
-
newMetaItem.initialValue = initialValue;
|
|
261
|
-
return newMetaItem;
|
|
262
|
-
}
|
|
263
|
-
static getAssetDescriptorColor(descriptor, fallbackColor) {
|
|
264
|
-
return descriptor && descriptor.color ? descriptor.color : fallbackColor;
|
|
265
|
-
}
|
|
266
|
-
static getAssetDescriptorIcon(descriptor, fallbackIcon) {
|
|
267
|
-
return descriptor && descriptor.icon ? descriptor.icon : fallbackIcon;
|
|
268
|
-
}
|
|
269
|
-
static hasMetaItem(descriptor, name) {
|
|
270
|
-
if (!descriptor || !descriptor.metaItemDescriptors) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
return !!descriptor.metaItemDescriptors.find((mid) => mid.urn === name);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
AssetModelUtil._assetDescriptors = [];
|
|
277
|
-
AssetModelUtil._attributeDescriptors = [];
|
|
278
|
-
AssetModelUtil._attributeValueDescriptors = [];
|
|
279
|
-
AssetModelUtil._metaItemDescriptors = [];
|
|
280
|
-
export class Manager {
|
|
281
|
-
constructor() {
|
|
282
|
-
this._authenticated = false;
|
|
283
|
-
this._ready = false;
|
|
284
|
-
this._name = "";
|
|
285
|
-
this._username = "";
|
|
286
|
-
this._keycloakUpdateTokenInterval = undefined;
|
|
287
|
-
this._managerVersion = "";
|
|
288
|
-
this._listeners = [];
|
|
289
|
-
this._displayRealm = "";
|
|
290
|
-
}
|
|
291
|
-
get username() {
|
|
292
|
-
return this._username;
|
|
293
|
-
}
|
|
294
|
-
get error() {
|
|
295
|
-
return this._error;
|
|
296
|
-
}
|
|
297
|
-
get authenticated() {
|
|
298
|
-
return this._authenticated;
|
|
299
|
-
}
|
|
300
|
-
get ready() {
|
|
301
|
-
return this._ready;
|
|
302
|
-
}
|
|
303
|
-
get config() {
|
|
304
|
-
return this._config;
|
|
305
|
-
}
|
|
306
|
-
get roles() {
|
|
307
|
-
const roleMap = new Map();
|
|
308
|
-
if (this._keycloak) {
|
|
309
|
-
if (this._keycloak.resourceAccess) {
|
|
310
|
-
if (this._config.clientId && this._keycloak.resourceAccess) {
|
|
311
|
-
Object.entries(this._keycloak.resourceAccess).forEach(([client, resourceObj]) => {
|
|
312
|
-
const roles = resourceObj.roles;
|
|
313
|
-
roleMap.set(client, roles);
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
else if (this._basicIdentity && this._basicIdentity.roles) {
|
|
319
|
-
roleMap.set(this._config.clientId, this._basicIdentity.roles.map((r) => r.name));
|
|
320
|
-
}
|
|
321
|
-
return roleMap;
|
|
322
|
-
}
|
|
323
|
-
get managerVersion() {
|
|
324
|
-
return this._managerVersion;
|
|
325
|
-
}
|
|
326
|
-
get isManagerAvailable() {
|
|
327
|
-
return this._managerVersion && this._managerVersion !== "";
|
|
328
|
-
}
|
|
329
|
-
get managerUrl() {
|
|
330
|
-
return this._config.managerUrl;
|
|
331
|
-
}
|
|
332
|
-
get keycloakUrl() {
|
|
333
|
-
return this._config.keycloakUrl;
|
|
334
|
-
}
|
|
335
|
-
get isError() {
|
|
336
|
-
return !!this._error;
|
|
337
|
-
}
|
|
338
|
-
get connectionStatus() {
|
|
339
|
-
return this._events && this._events.status;
|
|
340
|
-
}
|
|
341
|
-
get console() {
|
|
342
|
-
return this._console;
|
|
343
|
-
}
|
|
344
|
-
get consoleAppConfig() {
|
|
345
|
-
return this._consoleAppConfig;
|
|
346
|
-
}
|
|
347
|
-
get events() {
|
|
348
|
-
return this._events;
|
|
349
|
-
}
|
|
350
|
-
get rest() {
|
|
351
|
-
return rest;
|
|
352
|
-
}
|
|
353
|
-
get language() {
|
|
354
|
-
return i18next.language;
|
|
355
|
-
}
|
|
356
|
-
set language(lang) {
|
|
357
|
-
i18next.changeLanguage(lang);
|
|
358
|
-
this.console.storeData("LANGUAGE", lang);
|
|
359
|
-
}
|
|
360
|
-
get displayRealm() {
|
|
361
|
-
return this._displayRealm || this._config.realm;
|
|
362
|
-
}
|
|
363
|
-
set displayRealm(realm) {
|
|
364
|
-
if (!this.isSuperUser()) {
|
|
365
|
-
return;
|
|
366
|
-
}
|
|
367
|
-
this._displayRealm = realm;
|
|
368
|
-
this._emitEvent(OREvent.DISPLAY_REALM_CHANGED);
|
|
369
|
-
}
|
|
370
|
-
getEventProvider() {
|
|
371
|
-
return this.events;
|
|
372
|
-
}
|
|
373
|
-
get mapType() {
|
|
374
|
-
return this._config.mapType || MapType.VECTOR;
|
|
375
|
-
}
|
|
376
|
-
static normaliseConfig(config) {
|
|
377
|
-
const normalisedConfig = Object.assign({}, config);
|
|
378
|
-
if (!normalisedConfig.managerUrl || normalisedConfig.managerUrl === "") {
|
|
379
|
-
// Assume manager is running on same host as this code
|
|
380
|
-
normalisedConfig.managerUrl = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : "");
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
// Normalise by stripping any trailing slashes
|
|
384
|
-
normalisedConfig.managerUrl = normalisedConfig.managerUrl.replace(/\/+$/, "");
|
|
385
|
-
}
|
|
386
|
-
if (!normalisedConfig.realm || normalisedConfig.realm === "") {
|
|
387
|
-
// Assume master realm
|
|
388
|
-
normalisedConfig.realm = "master";
|
|
389
|
-
}
|
|
390
|
-
if (normalisedConfig.auth === Auth.KEYCLOAK) {
|
|
391
|
-
// Determine URL of keycloak server
|
|
392
|
-
if (!normalisedConfig.keycloakUrl || normalisedConfig.keycloakUrl === "") {
|
|
393
|
-
// Assume keycloak is running on same host as the manager
|
|
394
|
-
normalisedConfig.keycloakUrl = normalisedConfig.managerUrl + "/auth";
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
// Normalise by stripping any trailing slashes
|
|
398
|
-
normalisedConfig.keycloakUrl = normalisedConfig.keycloakUrl.replace(/\/+$/, "");
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
if (normalisedConfig.consoleAutoEnable === undefined) {
|
|
402
|
-
normalisedConfig.consoleAutoEnable = true;
|
|
403
|
-
}
|
|
404
|
-
if (!normalisedConfig.eventProviderType) {
|
|
405
|
-
normalisedConfig.eventProviderType = EventProviderType.WEBSOCKET;
|
|
406
|
-
}
|
|
407
|
-
if (!normalisedConfig.pollingIntervalMillis || normalisedConfig.pollingIntervalMillis < 5000) {
|
|
408
|
-
normalisedConfig.pollingIntervalMillis = 10000;
|
|
409
|
-
}
|
|
410
|
-
if (normalisedConfig.loadIcons === undefined) {
|
|
411
|
-
normalisedConfig.loadIcons = true;
|
|
412
|
-
}
|
|
413
|
-
if (normalisedConfig.loadTranslations === undefined) {
|
|
414
|
-
normalisedConfig.loadTranslations = ["or"];
|
|
415
|
-
}
|
|
416
|
-
if (normalisedConfig.translationsLoadPath === undefined) {
|
|
417
|
-
normalisedConfig.translationsLoadPath = "locales/{{lng}}/{{ns}}.json";
|
|
418
|
-
}
|
|
419
|
-
if (normalisedConfig.loadDescriptors === undefined) {
|
|
420
|
-
normalisedConfig.loadDescriptors = true;
|
|
421
|
-
}
|
|
422
|
-
if (normalisedConfig.clientId === undefined) {
|
|
423
|
-
normalisedConfig.clientId = "openremote";
|
|
424
|
-
}
|
|
425
|
-
return normalisedConfig;
|
|
426
|
-
}
|
|
427
|
-
isManagerSameOrigin() {
|
|
428
|
-
if (!this.ready) {
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
const managerUrl = new URL(this._config.managerUrl);
|
|
432
|
-
const windowUrl = window.location;
|
|
433
|
-
return managerUrl.protocol === windowUrl.protocol
|
|
434
|
-
&& managerUrl.hostname === windowUrl.hostname
|
|
435
|
-
&& managerUrl.port === windowUrl.port;
|
|
436
|
-
}
|
|
437
|
-
addListener(callback) {
|
|
438
|
-
const index = this._listeners.indexOf(callback);
|
|
439
|
-
if (index < 0) {
|
|
440
|
-
this._listeners.push(callback);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
removeListener(callback) {
|
|
444
|
-
const index = this._listeners.indexOf(callback);
|
|
445
|
-
if (index >= 0) {
|
|
446
|
-
this._listeners.splice(index, 1);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
init(config) {
|
|
450
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
451
|
-
if (this._config) {
|
|
452
|
-
console.log("Already initialised");
|
|
453
|
-
}
|
|
454
|
-
this._config = Manager.normaliseConfig(config);
|
|
455
|
-
let success = yield this.doAuthInit();
|
|
456
|
-
if (success) {
|
|
457
|
-
success = yield this.doInit();
|
|
458
|
-
}
|
|
459
|
-
if (success) {
|
|
460
|
-
success = this.doRestApiInit();
|
|
461
|
-
}
|
|
462
|
-
success = (yield this.doConsoleInit()) && success;
|
|
463
|
-
success = (yield this.doTranslateInit()) && success;
|
|
464
|
-
if (success) {
|
|
465
|
-
success = yield this.doDescriptorsInit();
|
|
466
|
-
yield this.getConsoleAppConfig();
|
|
467
|
-
}
|
|
468
|
-
// TODO: Reinstate this once websocket supports anonymous connections
|
|
469
|
-
// if (success) {
|
|
470
|
-
// success = await this.doEventsSubscriptionInit();
|
|
471
|
-
// }
|
|
472
|
-
if (success) {
|
|
473
|
-
if (this._readyCallback) {
|
|
474
|
-
yield this._readyCallback();
|
|
475
|
-
}
|
|
476
|
-
this._ready = true;
|
|
477
|
-
this._emitEvent(OREvent.READY);
|
|
478
|
-
}
|
|
479
|
-
this._displayRealm = config.realm;
|
|
480
|
-
return success;
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
doInit() {
|
|
484
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
485
|
-
// Check manager exists by calling the info endpoint
|
|
486
|
-
try {
|
|
487
|
-
const json = yield new Promise((resolve, reject) => {
|
|
488
|
-
const oReq = new XMLHttpRequest();
|
|
489
|
-
oReq.addEventListener("load", () => {
|
|
490
|
-
resolve(JSON.parse(oReq.responseText));
|
|
491
|
-
});
|
|
492
|
-
oReq.addEventListener("error", () => {
|
|
493
|
-
reject(new Error("Failed to contact the manager"));
|
|
494
|
-
});
|
|
495
|
-
oReq.open("GET", this._config.managerUrl + "/api/master/info");
|
|
496
|
-
oReq.send();
|
|
497
|
-
});
|
|
498
|
-
this._managerVersion = json && json.version ? json.version : "";
|
|
499
|
-
// Load material design and OR icon sets if requested
|
|
500
|
-
if (this._config.loadIcons) {
|
|
501
|
-
const response = yield fetch(manager.config.managerUrl + "/shared/mdi-icons.json");
|
|
502
|
-
const mdiIconSet = yield response.json();
|
|
503
|
-
IconSets.addIconSet("mdi", mdiIconSet);
|
|
504
|
-
IconSets.addIconSet("or", orIconSet);
|
|
505
|
-
}
|
|
506
|
-
return true;
|
|
507
|
-
}
|
|
508
|
-
catch (e) {
|
|
509
|
-
// TODO: Implement auto retry?
|
|
510
|
-
console.error("Failed to contact the manager", e);
|
|
511
|
-
this._setError(ORError.MANAGER_FAILED_TO_LOAD);
|
|
512
|
-
return false;
|
|
513
|
-
}
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
|
-
doTranslateInit() {
|
|
517
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
518
|
-
i18next.on("initialized", (options) => {
|
|
519
|
-
this._emitEvent(OREvent.TRANSLATE_INIT);
|
|
520
|
-
});
|
|
521
|
-
i18next.on("languageChanged", (lng) => {
|
|
522
|
-
moment.locale(lng);
|
|
523
|
-
this._emitEvent(OREvent.TRANSLATE_LANGUAGE_CHANGED);
|
|
524
|
-
});
|
|
525
|
-
// Look for language preference in local storage
|
|
526
|
-
const language = !this.console ? undefined : yield this.console.retrieveData("LANGUAGE");
|
|
527
|
-
const initOptions = {
|
|
528
|
-
lng: language,
|
|
529
|
-
fallbackLng: "en",
|
|
530
|
-
defaultNS: "app",
|
|
531
|
-
fallbackNS: "or",
|
|
532
|
-
ns: this.config.loadTranslations,
|
|
533
|
-
interpolation: {
|
|
534
|
-
format: function (value, format, lng) {
|
|
535
|
-
if (format === "uppercase")
|
|
536
|
-
return value.toUpperCase();
|
|
537
|
-
if (value instanceof Date) {
|
|
538
|
-
return moment(value).format(format);
|
|
539
|
-
}
|
|
540
|
-
return value;
|
|
541
|
-
}
|
|
542
|
-
},
|
|
543
|
-
backend: {
|
|
544
|
-
loadPath: (langs, namespaces) => {
|
|
545
|
-
if (namespaces.length === 1 && namespaces[0] === "or") {
|
|
546
|
-
return this.config.managerUrl + "/shared/locales/{{lng}}/{{ns}}.json";
|
|
547
|
-
}
|
|
548
|
-
if (this.config.translationsLoadPath) {
|
|
549
|
-
return this.config.translationsLoadPath;
|
|
550
|
-
}
|
|
551
|
-
return "locales/{{lng}}/{{ns}}.json";
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
if (this.config.configureTranslationsOptions) {
|
|
556
|
-
this.config.configureTranslationsOptions(initOptions);
|
|
557
|
-
}
|
|
558
|
-
try {
|
|
559
|
-
yield i18next.use(sprintf).use(i18nextXhr).init(initOptions);
|
|
560
|
-
}
|
|
561
|
-
catch (e) {
|
|
562
|
-
console.error(e);
|
|
563
|
-
this._setError(ORError.TRANSLATION_ERROR);
|
|
564
|
-
return false;
|
|
565
|
-
}
|
|
566
|
-
return true;
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
doDescriptorsInit() {
|
|
570
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
571
|
-
if (!this.config.loadDescriptors) {
|
|
572
|
-
return true;
|
|
573
|
-
}
|
|
574
|
-
try {
|
|
575
|
-
const assetDescriptorResponse = yield rest.api.AssetModelResource.getAssetDescriptors();
|
|
576
|
-
const attributeDescriptorResponse = yield rest.api.AssetModelResource.getAttributeDescriptors();
|
|
577
|
-
const attributeValueDescriptorResponse = yield rest.api.AssetModelResource.getAttributeValueDescriptors();
|
|
578
|
-
const metaItemDescriptorResponse = yield rest.api.AssetModelResource.getMetaItemDescriptors();
|
|
579
|
-
AssetModelUtil._assetDescriptors = assetDescriptorResponse.data;
|
|
580
|
-
AssetModelUtil._attributeDescriptors = attributeDescriptorResponse.data;
|
|
581
|
-
AssetModelUtil._attributeValueDescriptors = attributeValueDescriptorResponse.data;
|
|
582
|
-
AssetModelUtil._metaItemDescriptors = metaItemDescriptorResponse.data;
|
|
583
|
-
}
|
|
584
|
-
catch (e) {
|
|
585
|
-
console.error(e);
|
|
586
|
-
return false;
|
|
587
|
-
}
|
|
588
|
-
return true;
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
doAuthInit() {
|
|
592
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
593
|
-
let success = true;
|
|
594
|
-
switch (this._config.auth) {
|
|
595
|
-
case Auth.BASIC:
|
|
596
|
-
success = yield this.initialiseBasicAuth();
|
|
597
|
-
break;
|
|
598
|
-
case Auth.KEYCLOAK:
|
|
599
|
-
success = yield this.loadAndInitialiseKeycloak();
|
|
600
|
-
if (!success) {
|
|
601
|
-
// Try fallback to BASIC
|
|
602
|
-
console.log("Falling back to basic auth");
|
|
603
|
-
this._config.auth = Auth.BASIC;
|
|
604
|
-
return this.doAuthInit();
|
|
605
|
-
}
|
|
606
|
-
break;
|
|
607
|
-
case Auth.NONE:
|
|
608
|
-
// Nothing for us to do here
|
|
609
|
-
return true;
|
|
610
|
-
default:
|
|
611
|
-
this._setError(ORError.AUTH_TYPE_UNSUPPORTED);
|
|
612
|
-
return false;
|
|
613
|
-
}
|
|
614
|
-
// Add interceptor to inject authorization header on each request
|
|
615
|
-
rest.addRequestInterceptor((config) => {
|
|
616
|
-
if (!config.headers.Authorization) {
|
|
617
|
-
const authHeader = this.getAuthorizationHeader();
|
|
618
|
-
if (authHeader) {
|
|
619
|
-
config.headers.Authorization = authHeader;
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
return config;
|
|
623
|
-
});
|
|
624
|
-
return success;
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
doRestApiInit() {
|
|
628
|
-
rest.setTimeout(10000);
|
|
629
|
-
rest.initialise(this.getApiBaseUrl());
|
|
630
|
-
return true;
|
|
631
|
-
}
|
|
632
|
-
doEventsSubscriptionInit() {
|
|
633
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
634
|
-
let connected = false;
|
|
635
|
-
switch (this._config.eventProviderType) {
|
|
636
|
-
case EventProviderType.WEBSOCKET:
|
|
637
|
-
this._events = new WebSocketEventProvider(this._config.managerUrl);
|
|
638
|
-
this._events.subscribeStatusChange((status) => this._onEventProviderStatusChanged(status));
|
|
639
|
-
connected = yield this._events.connect();
|
|
640
|
-
break;
|
|
641
|
-
case EventProviderType.POLLING:
|
|
642
|
-
break;
|
|
643
|
-
}
|
|
644
|
-
if (!connected) {
|
|
645
|
-
this._setError(ORError.EVENTS_CONNECTION_ERROR);
|
|
646
|
-
}
|
|
647
|
-
return connected;
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
_onEventProviderStatusChanged(status) {
|
|
651
|
-
switch (status) {
|
|
652
|
-
case EventProviderStatus.DISCONNECTED:
|
|
653
|
-
this._emitEvent(OREvent.EVENTS_DISCONNECTED);
|
|
654
|
-
break;
|
|
655
|
-
case EventProviderStatus.CONNECTED:
|
|
656
|
-
this._emitEvent(OREvent.EVENTS_CONNECTED);
|
|
657
|
-
break;
|
|
658
|
-
case EventProviderStatus.CONNECTING:
|
|
659
|
-
this._emitEvent(OREvent.EVENTS_CONNECTING);
|
|
660
|
-
break;
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
doConsoleInit() {
|
|
664
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
665
|
-
try {
|
|
666
|
-
let orConsole = new Console(this._config.realm, this._config.consoleAutoEnable, () => {
|
|
667
|
-
this._emitEvent(OREvent.CONSOLE_READY);
|
|
668
|
-
});
|
|
669
|
-
this._console = orConsole;
|
|
670
|
-
yield orConsole.initialise();
|
|
671
|
-
this._emitEvent(OREvent.CONSOLE_INIT);
|
|
672
|
-
return true;
|
|
673
|
-
}
|
|
674
|
-
catch (e) {
|
|
675
|
-
this._setError(ORError.CONSOLE_ERROR);
|
|
676
|
-
return false;
|
|
677
|
-
}
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
getConsoleAppConfig() {
|
|
681
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
682
|
-
const consoleAppConfigResponse = yield this.rest.api.ConsoleAppResource.getAppConfig();
|
|
683
|
-
if (consoleAppConfigResponse.status === 200) {
|
|
684
|
-
this._consoleAppConfig = consoleAppConfigResponse.data;
|
|
685
|
-
}
|
|
686
|
-
});
|
|
687
|
-
}
|
|
688
|
-
logout(redirectUrl) {
|
|
689
|
-
if (this._keycloak) {
|
|
690
|
-
if (this.console.isMobile) {
|
|
691
|
-
this.console.storeData("REFRESH_TOKEN", null);
|
|
692
|
-
}
|
|
693
|
-
const options = redirectUrl && redirectUrl !== "" ? { redirectUri: redirectUrl } : null;
|
|
694
|
-
this._keycloak.logout(options);
|
|
695
|
-
}
|
|
696
|
-
else if (this._basicIdentity) {
|
|
697
|
-
this._basicIdentity = undefined;
|
|
698
|
-
if (redirectUrl) {
|
|
699
|
-
window.location.href = redirectUrl;
|
|
700
|
-
}
|
|
701
|
-
else {
|
|
702
|
-
window.location.reload();
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
login(options) {
|
|
707
|
-
switch (this._config.auth) {
|
|
708
|
-
case Auth.BASIC:
|
|
709
|
-
if (options && options.credentials) {
|
|
710
|
-
this._config.credentials = Object.assign({}, options.credentials);
|
|
711
|
-
}
|
|
712
|
-
this.doBasicLogin();
|
|
713
|
-
break;
|
|
714
|
-
case Auth.KEYCLOAK:
|
|
715
|
-
if (this._keycloak) {
|
|
716
|
-
const keycloakOptions = {};
|
|
717
|
-
if (options && options.redirectUrl && options.redirectUrl !== "") {
|
|
718
|
-
keycloakOptions.redirectUri = options.redirectUrl;
|
|
719
|
-
}
|
|
720
|
-
if (this.isMobile()) {
|
|
721
|
-
keycloakOptions.scope = "offline_access";
|
|
722
|
-
}
|
|
723
|
-
this._keycloak.login(keycloakOptions);
|
|
724
|
-
}
|
|
725
|
-
break;
|
|
726
|
-
case Auth.NONE:
|
|
727
|
-
break;
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
initialiseBasicAuth() {
|
|
731
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
732
|
-
if (!this.config.basicLoginProvider) {
|
|
733
|
-
console.log("No basicLoginProvider defined on config so cannot display login UI");
|
|
734
|
-
return false;
|
|
735
|
-
}
|
|
736
|
-
if (this.config.autoLogin) {
|
|
737
|
-
// Delay basic login until other inits are done
|
|
738
|
-
this._readyCallback = () => {
|
|
739
|
-
return this.doBasicLogin();
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
return true;
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
doBasicLogin() {
|
|
746
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
747
|
-
if (!this.config.basicLoginProvider) {
|
|
748
|
-
return;
|
|
749
|
-
}
|
|
750
|
-
let result = {
|
|
751
|
-
username: this._config.credentials ? this._config.credentials.username : "",
|
|
752
|
-
password: this._config.credentials ? this._config.credentials.password : "",
|
|
753
|
-
cancel: false,
|
|
754
|
-
closeCallback: undefined
|
|
755
|
-
};
|
|
756
|
-
let authenticated = false;
|
|
757
|
-
this._basicIdentity = {
|
|
758
|
-
roles: undefined,
|
|
759
|
-
token: undefined,
|
|
760
|
-
user: undefined
|
|
761
|
-
};
|
|
762
|
-
while (!authenticated) {
|
|
763
|
-
result = yield this.config.basicLoginProvider(result.username, result.password);
|
|
764
|
-
if (result.cancel) {
|
|
765
|
-
console.log("Basic authentication cancelled by user");
|
|
766
|
-
if (result.closeCallback) {
|
|
767
|
-
result.closeCallback(false);
|
|
768
|
-
}
|
|
769
|
-
break;
|
|
770
|
-
}
|
|
771
|
-
if (!result.username || !result.password) {
|
|
772
|
-
continue;
|
|
773
|
-
}
|
|
774
|
-
// Update basic token so we can use rest api to make calls
|
|
775
|
-
this._basicIdentity.token = btoa(result.username + ":" + result.password);
|
|
776
|
-
const userResponse = yield rest.api.UserResource.getCurrent();
|
|
777
|
-
const status = userResponse.status;
|
|
778
|
-
if (status === 200) {
|
|
779
|
-
console.log("Basic authentication successful");
|
|
780
|
-
authenticated = true;
|
|
781
|
-
this._basicIdentity.user = userResponse.data;
|
|
782
|
-
// Get user roles
|
|
783
|
-
const rolesResponse = yield rest.api.UserResource.getCurrentUserRoles();
|
|
784
|
-
this._basicIdentity.roles = rolesResponse.data;
|
|
785
|
-
// Undertow incorrectly returns 403 when no authorization header and a 401 when it is set and not valid
|
|
786
|
-
}
|
|
787
|
-
else if (status === 401 || status === 403) {
|
|
788
|
-
console.log("Basic authentication invalid credentials, trying again");
|
|
789
|
-
this._basicIdentity = undefined;
|
|
790
|
-
}
|
|
791
|
-
else {
|
|
792
|
-
console.log("Unkown response so aborting");
|
|
793
|
-
this._basicIdentity = undefined;
|
|
794
|
-
break;
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
this._setAuthenticated(authenticated);
|
|
798
|
-
if (result.closeCallback) {
|
|
799
|
-
result.closeCallback(authenticated);
|
|
800
|
-
}
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
isSuperUser() {
|
|
804
|
-
return this.getRealm() && this.getRealm() === "master" && this.hasRealmRole("admin");
|
|
805
|
-
}
|
|
806
|
-
getApiBaseUrl() {
|
|
807
|
-
let baseUrl = this._config.managerUrl;
|
|
808
|
-
baseUrl += "/api/" + this._config.realm + "/";
|
|
809
|
-
return baseUrl;
|
|
810
|
-
}
|
|
811
|
-
getAppName() {
|
|
812
|
-
let pathArr = location.pathname.split('/');
|
|
813
|
-
return pathArr.length >= 1 ? pathArr[1] : "";
|
|
814
|
-
}
|
|
815
|
-
hasRealmRole(role) {
|
|
816
|
-
return this._keycloak && this._keycloak.hasRealmRole(role);
|
|
817
|
-
}
|
|
818
|
-
hasRole(role, client = this._config.clientId) {
|
|
819
|
-
const roles = this.roles;
|
|
820
|
-
return roles && roles.has(client) && roles.get(client).indexOf(role) >= 0;
|
|
821
|
-
}
|
|
822
|
-
getAuthorizationHeader() {
|
|
823
|
-
if (this._keycloak) {
|
|
824
|
-
return "Bearer " + this._keycloak.token;
|
|
825
|
-
}
|
|
826
|
-
if (this.getBasicToken()) {
|
|
827
|
-
return "Basic " + this.getBasicToken();
|
|
828
|
-
}
|
|
829
|
-
return undefined;
|
|
830
|
-
}
|
|
831
|
-
getKeycloakToken() {
|
|
832
|
-
if (this._keycloak) {
|
|
833
|
-
return this._keycloak.token;
|
|
834
|
-
}
|
|
835
|
-
return undefined;
|
|
836
|
-
}
|
|
837
|
-
getBasicToken() {
|
|
838
|
-
return this._basicIdentity ? this._basicIdentity.token : undefined;
|
|
839
|
-
}
|
|
840
|
-
getRealm() {
|
|
841
|
-
if (this._config) {
|
|
842
|
-
return this._config.realm;
|
|
843
|
-
}
|
|
844
|
-
return undefined;
|
|
845
|
-
}
|
|
846
|
-
isMobile() {
|
|
847
|
-
return this.console && this.console.isMobile;
|
|
848
|
-
}
|
|
849
|
-
isKeycloak() {
|
|
850
|
-
return !!this._keycloak;
|
|
851
|
-
}
|
|
852
|
-
_onAuthenticated() {
|
|
853
|
-
// If native shell is enabled, we need an offline refresh token
|
|
854
|
-
if (this.console && this.console.isMobile && this.config.auth === Auth.KEYCLOAK) {
|
|
855
|
-
if (this._keycloak && this._keycloak.refreshTokenParsed.typ === "Offline") {
|
|
856
|
-
console.debug("Storing offline refresh token");
|
|
857
|
-
this.console.storeData("REFRESH_TOKEN", this._keycloak.refreshToken);
|
|
858
|
-
}
|
|
859
|
-
else {
|
|
860
|
-
this.login();
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
// NOTE: The below works with Keycloak 2.x JS API - They made breaking changes in newer versions
|
|
865
|
-
// so this will need updating.
|
|
866
|
-
loadAndInitialiseKeycloak() {
|
|
867
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
868
|
-
try {
|
|
869
|
-
// There's a bug in some Keycloak versions which means the init promise doesn't resolve
|
|
870
|
-
// so putting a check in place; wrap keycloak promise in proper ES6 promise
|
|
871
|
-
let keycloakPromise = null;
|
|
872
|
-
// Load the keycloak JS API
|
|
873
|
-
yield Util.loadJs(this._config.keycloakUrl + "/js/keycloak.js");
|
|
874
|
-
// Should have Keycloak global var now
|
|
875
|
-
if (!window.Keycloak) {
|
|
876
|
-
console.log("Keycloak global variable not found probably failed to load keycloak or manager doesn't support it");
|
|
877
|
-
return false;
|
|
878
|
-
}
|
|
879
|
-
// Initialise keycloak
|
|
880
|
-
this._keycloak = window.Keycloak({
|
|
881
|
-
clientId: this._config.clientId,
|
|
882
|
-
realm: this._config.realm,
|
|
883
|
-
url: this._config.keycloakUrl
|
|
884
|
-
});
|
|
885
|
-
this._keycloak.onAuthSuccess = () => {
|
|
886
|
-
if (keycloakPromise) {
|
|
887
|
-
keycloakPromise(true);
|
|
888
|
-
}
|
|
889
|
-
};
|
|
890
|
-
this._keycloak.onAuthError = () => {
|
|
891
|
-
this._setAuthenticated(false);
|
|
892
|
-
};
|
|
893
|
-
try {
|
|
894
|
-
// Try to use a stored offline refresh token if defined
|
|
895
|
-
const offlineToken = yield this._getNativeOfflineRefreshToken();
|
|
896
|
-
const authenticated = yield new Promise(((resolve, reject) => {
|
|
897
|
-
keycloakPromise = resolve;
|
|
898
|
-
this._keycloak.init({
|
|
899
|
-
checkLoginIframe: false,
|
|
900
|
-
onLoad: this._config.autoLogin ? "login-required" : "check-sso",
|
|
901
|
-
refreshToken: offlineToken
|
|
902
|
-
}).success((auth) => {
|
|
903
|
-
resolve(auth);
|
|
904
|
-
}).error(() => {
|
|
905
|
-
reject();
|
|
906
|
-
});
|
|
907
|
-
}));
|
|
908
|
-
keycloakPromise = null;
|
|
909
|
-
if (authenticated) {
|
|
910
|
-
this._name = this._keycloak.tokenParsed.name;
|
|
911
|
-
this._username = this._keycloak.tokenParsed.preferred_username;
|
|
912
|
-
// Update the access token every 10s (note keycloak will only update if expiring within configured
|
|
913
|
-
// time period.
|
|
914
|
-
if (this._keycloakUpdateTokenInterval) {
|
|
915
|
-
clearInterval(this._keycloakUpdateTokenInterval);
|
|
916
|
-
delete this._keycloakUpdateTokenInterval;
|
|
917
|
-
}
|
|
918
|
-
this._keycloakUpdateTokenInterval = window.setInterval(() => {
|
|
919
|
-
this.updateKeycloakAccessToken();
|
|
920
|
-
}, 10000);
|
|
921
|
-
this._onAuthenticated();
|
|
922
|
-
}
|
|
923
|
-
this._setAuthenticated(authenticated);
|
|
924
|
-
return true;
|
|
925
|
-
}
|
|
926
|
-
catch (e) {
|
|
927
|
-
console.error(e);
|
|
928
|
-
keycloakPromise = null;
|
|
929
|
-
this._setAuthenticated(false);
|
|
930
|
-
return false;
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
catch (error) {
|
|
934
|
-
this._setError(ORError.AUTH_FAILED);
|
|
935
|
-
console.error("Failed to load Keycloak");
|
|
936
|
-
return false;
|
|
937
|
-
}
|
|
938
|
-
});
|
|
939
|
-
}
|
|
940
|
-
updateKeycloakAccessToken() {
|
|
941
|
-
// Access token must be good for X more seconds, should be half of Constants.ACCESS_TOKEN_LIFESPAN_SECONDS
|
|
942
|
-
return new Promise(() => {
|
|
943
|
-
this._keycloak.updateToken(30)
|
|
944
|
-
.success((tokenRefreshed) => {
|
|
945
|
-
// If refreshed from server, it means the refresh token was still good for another access token
|
|
946
|
-
console.debug("Access token update success, refreshed from server: " + tokenRefreshed);
|
|
947
|
-
return tokenRefreshed;
|
|
948
|
-
})
|
|
949
|
-
.error(() => {
|
|
950
|
-
// Refresh token expired (either SSO max session duration or offline idle timeout), see
|
|
951
|
-
// IDENTITY_SESSION_MAX_MINUTES and IDENTITY_SESSION_OFFLINE_TIMEOUT_MINUTES server config
|
|
952
|
-
console.info("Access token update failed, refresh token expired, login required");
|
|
953
|
-
this._keycloak.clearToken();
|
|
954
|
-
this._keycloak.login();
|
|
955
|
-
});
|
|
956
|
-
});
|
|
957
|
-
}
|
|
958
|
-
_getNativeOfflineRefreshToken() {
|
|
959
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
960
|
-
if (this.console && this.console.isMobile) {
|
|
961
|
-
return yield this.console.retrieveData("REFRESH_TOKEN");
|
|
962
|
-
}
|
|
963
|
-
});
|
|
964
|
-
}
|
|
965
|
-
_emitEvent(event) {
|
|
966
|
-
window.setTimeout(() => {
|
|
967
|
-
let listeners = this._listeners.slice();
|
|
968
|
-
for (const listener of listeners) {
|
|
969
|
-
listener(event);
|
|
970
|
-
}
|
|
971
|
-
}, 0);
|
|
972
|
-
}
|
|
973
|
-
_setError(error) {
|
|
974
|
-
this._error = error;
|
|
975
|
-
this._emitEvent(OREvent.ERROR);
|
|
976
|
-
}
|
|
977
|
-
// TODO: Remove events logic once websocket supports anonymous connections
|
|
978
|
-
_setAuthenticated(authenticated) {
|
|
979
|
-
this._authenticated = authenticated;
|
|
980
|
-
if (authenticated) {
|
|
981
|
-
if (!this._events) {
|
|
982
|
-
this.doEventsSubscriptionInit();
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
else {
|
|
986
|
-
if (this._events) {
|
|
987
|
-
this._events.disconnect();
|
|
988
|
-
}
|
|
989
|
-
this._events = undefined;
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
export const manager = new Manager(); // Needed for webpack bundling
|
|
994
|
-
export const IconSets = new ORIconSets();
|
|
995
|
-
export default manager;
|
|
996
|
-
//# sourceMappingURL=index.js.map
|