@sumaris-net/ngx-components 0.28.4 → 1.0.2
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/bundles/sumaris-net.ngx-components.umd.js +296 -310
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +2 -2
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/doc/changelog.md +5 -0
- package/esm2015/src/app/core/graphql/graphql.service.js +5 -8
- package/esm2015/src/app/core/services/account.service.js +177 -188
- package/esm2015/src/app/core/services/base-entity-service.class.js +9 -7
- package/esm2015/src/app/core/services/base-graphql-service.class.js +7 -2
- package/esm2015/src/app/core/services/config.service.js +9 -54
- package/esm2015/src/app/core/services/model/account.model.js +1 -1
- package/esm2015/src/app/core/services/model/settings.model.js +29 -2
- package/esm2015/src/app/core/services/network.service.js +5 -7
- package/esm2015/src/app/core/services/storage/entities-storage.service.js +3 -6
- package/esm2015/src/app/shared/functions.js +8 -5
- package/esm2015/src/app/shared/services/startable-service.class.js +13 -2
- package/esm2015/src/app/shared/services/translate-context.service.js +4 -4
- package/fesm2015/sumaris-net.ngx-components.js +250 -268
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +1 -1
- package/src/app/core/graphql/graphql.service.d.ts +0 -1
- package/src/app/core/services/account.service.d.ts +8 -21
- package/src/app/core/services/base-entity-service.class.d.ts +1 -0
- package/src/app/core/services/base-graphql-service.class.d.ts +3 -2
- package/src/app/core/services/config.service.d.ts +2 -9
- package/src/app/core/services/model/settings.model.d.ts +2 -0
- package/src/app/core/services/network.service.d.ts +2 -2
- package/src/app/core/services/storage/entities-storage.service.d.ts +0 -1
- package/src/app/shared/services/startable-service.class.d.ts +3 -1
- package/sumaris-net.ngx-components.metadata.json +1 -1
|
@@ -250,8 +250,11 @@ function suggestFromArray(items, value, opts) {
|
|
|
250
250
|
return { data: [value] };
|
|
251
251
|
value = (typeof value === 'string' && value !== '*') && value.toUpperCase() || undefined;
|
|
252
252
|
const keys = opts && (opts.searchAttribute && [opts.searchAttribute] || opts.searchAttributes) || ['label'];
|
|
253
|
+
if (!items) {
|
|
254
|
+
return { data: [], total: 0 };
|
|
255
|
+
}
|
|
253
256
|
// Filter items
|
|
254
|
-
if (isNotNilOrBlank(value)
|
|
257
|
+
if (isNotNilOrBlank(value)) {
|
|
255
258
|
// If wildcard, search using regexp
|
|
256
259
|
if (value.indexOf('*') !== -1) {
|
|
257
260
|
value = value.replace('*', '.*');
|
|
@@ -263,13 +266,13 @@ function suggestFromArray(items, value, opts) {
|
|
|
263
266
|
}
|
|
264
267
|
}
|
|
265
268
|
// Exclude ids
|
|
266
|
-
if (
|
|
269
|
+
if (isNotEmptyArray(opts === null || opts === void 0 ? void 0 : opts.excludedIds)) {
|
|
267
270
|
items = items.filter(v => !opts.excludedIds.includes(+v['id']));
|
|
268
271
|
}
|
|
269
272
|
// Sort
|
|
270
|
-
items
|
|
273
|
+
items.sort(propertiesPathComparator(keys));
|
|
271
274
|
// Truncate if need
|
|
272
|
-
const total =
|
|
275
|
+
const total = items.length || 0;
|
|
273
276
|
if (opts) {
|
|
274
277
|
if (opts.offset > 0) {
|
|
275
278
|
items = items.slice(opts.offset);
|
|
@@ -2437,7 +2440,7 @@ class TranslateContextService {
|
|
|
2437
2440
|
const contextualKeys = this.contextualKeys(key, context);
|
|
2438
2441
|
// Return the contextual translation, or default of not exists
|
|
2439
2442
|
return this.translate.get(contextualKeys, interpolateParams)
|
|
2440
|
-
.pipe(map(translations => this.findFirstValid(contextualKeys, translations)
|
|
2443
|
+
.pipe(map(translations => this.findFirstValid(contextualKeys, translations)));
|
|
2441
2444
|
}
|
|
2442
2445
|
instant(key, context, interpolateParams) {
|
|
2443
2446
|
// No context: do a normal translate
|
|
@@ -2446,7 +2449,7 @@ class TranslateContextService {
|
|
|
2446
2449
|
// Compute a contextual i18n key, using the context as suffix
|
|
2447
2450
|
const contextualKeys = this.contextualKeys(key, context);
|
|
2448
2451
|
const translations = this.translate.instant(contextualKeys, interpolateParams);
|
|
2449
|
-
return this.findFirstValid(contextualKeys, translations)
|
|
2452
|
+
return this.findFirstValid(contextualKeys, translations);
|
|
2450
2453
|
}
|
|
2451
2454
|
/**
|
|
2452
2455
|
* Compute contextual i18n keys, using the context as suffix.<br>
|
|
@@ -2491,7 +2494,7 @@ class TranslateContextService {
|
|
|
2491
2494
|
if (translations[key] !== key)
|
|
2492
2495
|
return translations[key];
|
|
2493
2496
|
}
|
|
2494
|
-
return
|
|
2497
|
+
return translations[keys[keys.length - 1]]; // Return the last keys translation
|
|
2495
2498
|
}
|
|
2496
2499
|
}
|
|
2497
2500
|
TranslateContextService.ɵprov = i0.ɵɵdefineInjectable({ factory: function TranslateContextService_Factory() { return new TranslateContextService(i0.ɵɵinject(i1$1.TranslateService)); }, token: TranslateContextService, providedIn: "root" });
|
|
@@ -7757,6 +7760,9 @@ class StartableService {
|
|
|
7757
7760
|
this._startByReadyFunction = true; // should start when calling ready() ?
|
|
7758
7761
|
this._data = null;
|
|
7759
7762
|
this._started = false;
|
|
7763
|
+
this._startPromise = null;
|
|
7764
|
+
this._startPrerequisite = null;
|
|
7765
|
+
this._subscription = null;
|
|
7760
7766
|
this._startPrerequisite = prerequisiteService
|
|
7761
7767
|
? () => prerequisiteService.ready()
|
|
7762
7768
|
: () => Promise.resolve();
|
|
@@ -7786,6 +7792,10 @@ class StartableService {
|
|
|
7786
7792
|
stop() {
|
|
7787
7793
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7788
7794
|
try {
|
|
7795
|
+
if (this._subscription) {
|
|
7796
|
+
this._subscription.unsubscribe();
|
|
7797
|
+
this._subscription = null;
|
|
7798
|
+
}
|
|
7789
7799
|
yield this.ngOnStop();
|
|
7790
7800
|
this._started = false;
|
|
7791
7801
|
this._startPromise = undefined;
|
|
@@ -7820,6 +7830,10 @@ class StartableService {
|
|
|
7820
7830
|
return waitFor(() => this._started)
|
|
7821
7831
|
.then(() => this._data);
|
|
7822
7832
|
}
|
|
7833
|
+
registerSubscription(sub) {
|
|
7834
|
+
this._subscription = this._subscription || new Subscription();
|
|
7835
|
+
return this._subscription.add(sub);
|
|
7836
|
+
}
|
|
7823
7837
|
ngOnStop() {
|
|
7824
7838
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7825
7839
|
// Can be override by subclasses
|
|
@@ -10023,7 +10037,6 @@ class NetworkService extends StartableService {
|
|
|
10023
10037
|
this.onPeerChanges = this.onStart.pipe(map(peer => peer && peer.url), filter(isNotNilOrBlank), distinctUntilChanged());
|
|
10024
10038
|
this.onNetworkStatusChanges = new BehaviorSubject(null);
|
|
10025
10039
|
this.onResetNetworkCache = new EventEmitter(true);
|
|
10026
|
-
this._subscription = new Subscription();
|
|
10027
10040
|
this._listeners = {};
|
|
10028
10041
|
this._mobile = this.platform.is('mobile');
|
|
10029
10042
|
if (this._mobile) {
|
|
@@ -10184,7 +10197,8 @@ class NetworkService extends StartableService {
|
|
|
10184
10197
|
/**
|
|
10185
10198
|
* Check if the peer is alive
|
|
10186
10199
|
*
|
|
10187
|
-
* @param
|
|
10200
|
+
* @param peer
|
|
10201
|
+
* @param opts
|
|
10188
10202
|
*/
|
|
10189
10203
|
checkPeerAlive(peer, opts) {
|
|
10190
10204
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10324,8 +10338,8 @@ class NetworkService extends StartableService {
|
|
|
10324
10338
|
this.startRefreshTimer();
|
|
10325
10339
|
// Listen for device network changes
|
|
10326
10340
|
if (this.network) {
|
|
10327
|
-
this.
|
|
10328
|
-
this.
|
|
10341
|
+
this.registerSubscription(this.network.onDisconnect().subscribe(() => this.onDeviceConnectionChanged('none')));
|
|
10342
|
+
this.registerSubscription(this.network.onConnect().subscribe(() => this.onDeviceConnectionChanged(this.network.type)));
|
|
10329
10343
|
}
|
|
10330
10344
|
});
|
|
10331
10345
|
}
|
|
@@ -10336,8 +10350,6 @@ class NetworkService extends StartableService {
|
|
|
10336
10350
|
if (this._timerRefreshCondition() === false) {
|
|
10337
10351
|
this.stopRefreshTimer();
|
|
10338
10352
|
}
|
|
10339
|
-
this._subscription.unsubscribe();
|
|
10340
|
-
this._subscription = new Subscription();
|
|
10341
10353
|
});
|
|
10342
10354
|
}
|
|
10343
10355
|
/**
|
|
@@ -11032,7 +11044,6 @@ class EntitiesStorage extends StartableService {
|
|
|
11032
11044
|
this.progressBarService = progressBarService;
|
|
11033
11045
|
this.storage = storage;
|
|
11034
11046
|
this.environment = environment;
|
|
11035
|
-
this._subscription = new Subscription();
|
|
11036
11047
|
this._$save = new EventEmitter(true);
|
|
11037
11048
|
this._dirty = false;
|
|
11038
11049
|
this._saving = false;
|
|
@@ -11325,7 +11336,7 @@ class EntitiesStorage extends StartableService {
|
|
|
11325
11336
|
// Restore sequences
|
|
11326
11337
|
yield this.restoreLocally();
|
|
11327
11338
|
// Start a save timer
|
|
11328
|
-
this.
|
|
11339
|
+
this.registerSubscription(merge(this._$save, timer(this._saveTimerPeriod, this._saveTimerPeriod))
|
|
11329
11340
|
.pipe(
|
|
11330
11341
|
// Avoid to many call (e.g. when $save AND timer are triggered
|
|
11331
11342
|
throttleTime(this._saveTimerPeriod))
|
|
@@ -11336,8 +11347,6 @@ class EntitiesStorage extends StartableService {
|
|
|
11336
11347
|
}
|
|
11337
11348
|
ngOnStop() {
|
|
11338
11349
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11339
|
-
this._subscription.unsubscribe();
|
|
11340
|
-
this._subscription = new Subscription();
|
|
11341
11350
|
if (this.dirty) {
|
|
11342
11351
|
yield this.storeLocally();
|
|
11343
11352
|
}
|
|
@@ -11519,7 +11528,34 @@ let UserSettings = UserSettings_1 = class UserSettings extends Entity {
|
|
|
11519
11528
|
}
|
|
11520
11529
|
this.nonce = source.nonce;
|
|
11521
11530
|
}
|
|
11531
|
+
merge(source, includesProperties) {
|
|
11532
|
+
if (!source)
|
|
11533
|
+
return; // Skip
|
|
11534
|
+
// Reset content
|
|
11535
|
+
this.content = {};
|
|
11536
|
+
let hasChanges = false;
|
|
11537
|
+
// For each property of source object
|
|
11538
|
+
Object.keys(source)
|
|
11539
|
+
.forEach(key => {
|
|
11540
|
+
// If property exists in UserSettings class: store it directly
|
|
11541
|
+
if (UserSettings_1.SETTINGS_PROPERTIES.includes(key)) {
|
|
11542
|
+
if (!equals(this[key], source[key])) {
|
|
11543
|
+
this[key] = source[key];
|
|
11544
|
+
hasChanges = true;
|
|
11545
|
+
}
|
|
11546
|
+
}
|
|
11547
|
+
// Else, store property into the 'content' map
|
|
11548
|
+
else if (includesProperties && includesProperties.includes(key)) {
|
|
11549
|
+
if (!equals(this.content[key], source[key])) {
|
|
11550
|
+
this.content[key] = Object.assign({}, source[key]);
|
|
11551
|
+
hasChanges = true;
|
|
11552
|
+
}
|
|
11553
|
+
}
|
|
11554
|
+
});
|
|
11555
|
+
return hasChanges;
|
|
11556
|
+
}
|
|
11522
11557
|
};
|
|
11558
|
+
UserSettings.SETTINGS_PROPERTIES = ['locale', 'latLongFormat'];
|
|
11523
11559
|
UserSettings = UserSettings_1 = __decorate([
|
|
11524
11560
|
EntityClass({ typename: 'UserSettingsVO' })
|
|
11525
11561
|
], UserSettings);
|
|
@@ -11932,7 +11968,6 @@ class GraphqlService extends StartableService {
|
|
|
11932
11968
|
this.cryptoService = cryptoService;
|
|
11933
11969
|
this.environment = environment;
|
|
11934
11970
|
this.typePolicies = typePolicies;
|
|
11935
|
-
this._subscription = new Subscription();
|
|
11936
11971
|
this.connectionParams = {};
|
|
11937
11972
|
this.onNetworkError = new Subject();
|
|
11938
11973
|
this.customErrors = {};
|
|
@@ -12432,7 +12467,7 @@ class GraphqlService extends StartableService {
|
|
|
12432
12467
|
});
|
|
12433
12468
|
// Creating a mutation queue
|
|
12434
12469
|
const queueLink = new QueueLink();
|
|
12435
|
-
this.
|
|
12470
|
+
this.registerSubscription(this._networkStatusChanged$
|
|
12436
12471
|
.subscribe(type => {
|
|
12437
12472
|
// Network is offline: start buffering into queue
|
|
12438
12473
|
if (type === 'none') {
|
|
@@ -12495,9 +12530,9 @@ class GraphqlService extends StartableService {
|
|
|
12495
12530
|
}
|
|
12496
12531
|
}
|
|
12497
12532
|
// Listen for network restart
|
|
12498
|
-
this.
|
|
12533
|
+
this.registerSubscription(this.network.on('start', () => this.restart()));
|
|
12499
12534
|
// Listen for clear cache request, from network
|
|
12500
|
-
this.
|
|
12535
|
+
this.registerSubscription(this.network.on('resetCache', () => this.clearCache()));
|
|
12501
12536
|
console.info('[graphql] Starting graphql [OK]');
|
|
12502
12537
|
return client;
|
|
12503
12538
|
});
|
|
@@ -12505,8 +12540,6 @@ class GraphqlService extends StartableService {
|
|
|
12505
12540
|
ngOnStop() {
|
|
12506
12541
|
return __awaiter(this, void 0, void 0, function* () {
|
|
12507
12542
|
console.info('[graphql] Stopping graphql service...');
|
|
12508
|
-
this._subscription.unsubscribe();
|
|
12509
|
-
this._subscription = new Subscription();
|
|
12510
12543
|
yield this.resetClient();
|
|
12511
12544
|
});
|
|
12512
12545
|
}
|
|
@@ -12625,8 +12658,9 @@ const sha256 = require('hash.js/lib/hash/sha/256');
|
|
|
12625
12658
|
class BaseGraphqlServiceOptions {
|
|
12626
12659
|
}
|
|
12627
12660
|
// eslint-disable-next-line @angular-eslint/directive-class-suffix
|
|
12628
|
-
class BaseGraphqlService {
|
|
12661
|
+
class BaseGraphqlService extends StartableService {
|
|
12629
12662
|
constructor(graphql, options) {
|
|
12663
|
+
super(graphql);
|
|
12630
12664
|
this.graphql = graphql;
|
|
12631
12665
|
this._mutableWatchQueries = [];
|
|
12632
12666
|
// Max updated queries, for this entity.
|
|
@@ -12818,6 +12852,9 @@ class BaseGraphqlService {
|
|
|
12818
12852
|
return { query, variables };
|
|
12819
12853
|
});
|
|
12820
12854
|
}
|
|
12855
|
+
ngOnStart() {
|
|
12856
|
+
return Promise.resolve(null);
|
|
12857
|
+
}
|
|
12821
12858
|
}
|
|
12822
12859
|
BaseGraphqlService.decorators = [
|
|
12823
12860
|
{ type: Directive }
|
|
@@ -12951,18 +12988,16 @@ class AccountService extends BaseGraphqlService {
|
|
|
12951
12988
|
this.onChange = new Subject();
|
|
12952
12989
|
this.onAuthTokenChange = new Subject();
|
|
12953
12990
|
this.onAuthBasicChange = new Subject();
|
|
12954
|
-
this.
|
|
12991
|
+
this._cache = {
|
|
12955
12992
|
loaded: false,
|
|
12956
12993
|
keypair: null,
|
|
12957
12994
|
authToken: null,
|
|
12958
12995
|
authBasic: null,
|
|
12959
12996
|
pubkey: null,
|
|
12960
12997
|
mainProfile: null,
|
|
12961
|
-
account: null,
|
|
12962
12998
|
person: null,
|
|
12963
12999
|
department: null
|
|
12964
13000
|
};
|
|
12965
|
-
this._started = false;
|
|
12966
13001
|
this._$additionalFields = new BehaviorSubject([]);
|
|
12967
13002
|
this._tokenType$ = new BehaviorSubject(undefined);
|
|
12968
13003
|
this._debug = !environment.production;
|
|
@@ -12972,41 +13007,31 @@ class AccountService extends BaseGraphqlService {
|
|
|
12972
13007
|
// Send auth token to the graphql layer, when changed
|
|
12973
13008
|
this.onAuthTokenChange.subscribe((token) => this.graphql.setAuthToken(token));
|
|
12974
13009
|
this.onAuthBasicChange.subscribe((basic) => this.graphql.setAuthBasic(basic));
|
|
12975
|
-
// Listen graphql start (or restart)
|
|
12976
|
-
this.graphql.onStart.subscribe(() => __awaiter(this, void 0, void 0, function* () {
|
|
12977
|
-
if (!this._started) {
|
|
12978
|
-
this.ready();
|
|
12979
|
-
}
|
|
12980
|
-
if (this._started && this.isLogin()) {
|
|
12981
|
-
console.debug('[account] Restarting, to retry to authenticate...');
|
|
12982
|
-
this.restart();
|
|
12983
|
-
}
|
|
12984
|
-
}));
|
|
12985
13010
|
// Force network to wait account service, after getting connection to the peer
|
|
12986
13011
|
this.network.on('beforeTryOnlineFinish', (online) => __awaiter(this, void 0, void 0, function* () {
|
|
12987
13012
|
// If online, wait a full restart, because it can force offline mode
|
|
12988
|
-
if (online && (!this.
|
|
12989
|
-
console.debug('[account] Force networkService.tryOnline() to wait, that account service is restarted...');
|
|
12990
|
-
|
|
12991
|
-
|
|
12992
|
-
|
|
13013
|
+
if (online && (!this.started || this.isLogin())) {
|
|
13014
|
+
console.debug('[account] Force networkService.tryOnline() to wait, that graphql and account service is restarted...');
|
|
13015
|
+
yield sleep(500); // wait graphql service to be restarted
|
|
13016
|
+
if (!this.started)
|
|
13017
|
+
yield this.ready();
|
|
12993
13018
|
}
|
|
12994
13019
|
}));
|
|
12995
13020
|
}
|
|
12996
13021
|
get account() {
|
|
12997
|
-
return this.
|
|
13022
|
+
return this._cache.loaded ? this._data : undefined;
|
|
12998
13023
|
}
|
|
12999
13024
|
get person() {
|
|
13000
|
-
if (this.
|
|
13001
|
-
this.
|
|
13025
|
+
if (this._cache.loaded && !this._cache.person) {
|
|
13026
|
+
this._cache.person = this._cache.loaded ? this._data.asPerson() : undefined;
|
|
13002
13027
|
}
|
|
13003
|
-
return this.
|
|
13028
|
+
return this._cache.person;
|
|
13004
13029
|
}
|
|
13005
13030
|
get department() {
|
|
13006
|
-
if (this.
|
|
13007
|
-
this.
|
|
13031
|
+
if (this._cache.loaded && !this._cache.department) {
|
|
13032
|
+
this._cache.department = this._cache.loaded ? this._data.asPerson().department : undefined;
|
|
13008
13033
|
}
|
|
13009
|
-
return this.
|
|
13034
|
+
return this._cache.department;
|
|
13010
13035
|
}
|
|
13011
13036
|
get tokenType() {
|
|
13012
13037
|
return this._tokenType$.value;
|
|
@@ -13016,91 +13041,73 @@ class AccountService extends BaseGraphqlService {
|
|
|
13016
13041
|
console.info('[account] Using authentication token type: ' + value);
|
|
13017
13042
|
this._tokenType$.next(value);
|
|
13018
13043
|
// Reset values
|
|
13019
|
-
this.
|
|
13044
|
+
this._cache.authToken = undefined;
|
|
13020
13045
|
this.onAuthTokenChange.next(undefined);
|
|
13021
|
-
this.
|
|
13046
|
+
this._cache.authBasic = undefined;
|
|
13022
13047
|
this.onAuthBasicChange.next(undefined);
|
|
13023
13048
|
}
|
|
13024
13049
|
}
|
|
13025
|
-
|
|
13026
|
-
if (this._startPromise)
|
|
13027
|
-
return this._startPromise;
|
|
13028
|
-
if (this._started)
|
|
13029
|
-
return Promise.resolve(this.account);
|
|
13030
|
-
// Restoring local settings
|
|
13031
|
-
this._startPromise = Promise.all([
|
|
13032
|
-
this.settings.ready(),
|
|
13033
|
-
// Wait token type to be set
|
|
13034
|
-
firstNotNilPromise(this._tokenType$)
|
|
13035
|
-
])
|
|
13036
|
-
.then(() => this.restoreLocally())
|
|
13037
|
-
.then(() => {
|
|
13038
|
-
this._started = true;
|
|
13039
|
-
this._startPromise = undefined;
|
|
13040
|
-
return this.account;
|
|
13041
|
-
});
|
|
13042
|
-
return this._startPromise;
|
|
13043
|
-
}
|
|
13044
|
-
get started() {
|
|
13045
|
-
return this._started;
|
|
13046
|
-
}
|
|
13047
|
-
stop() {
|
|
13050
|
+
ngOnStart() {
|
|
13048
13051
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13049
|
-
|
|
13050
|
-
this.
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
if (
|
|
13057
|
-
|
|
13058
|
-
this.
|
|
13059
|
-
if (hadAuthToken)
|
|
13060
|
-
this.onAuthTokenChange.next(undefined);
|
|
13061
|
-
if (hadAuthBasic)
|
|
13062
|
-
this.onAuthBasicChange.next(undefined);
|
|
13052
|
+
yield Promise.all([
|
|
13053
|
+
this.settings.ready(),
|
|
13054
|
+
// Wait token type to be set
|
|
13055
|
+
firstNotNilPromise(this._tokenType$)
|
|
13056
|
+
]);
|
|
13057
|
+
// Listen graphql start (or restart)
|
|
13058
|
+
this.registerSubscription(this.graphql.onStart.subscribe(() => {
|
|
13059
|
+
if (this.started && this.isLogin()) {
|
|
13060
|
+
console.debug('[account] Restarting, to retry to authenticate...');
|
|
13061
|
+
this.restart();
|
|
13063
13062
|
}
|
|
13064
|
-
}
|
|
13063
|
+
}));
|
|
13064
|
+
yield this.restoreLocally();
|
|
13065
|
+
yield this.listenSettings();
|
|
13066
|
+
return this._data;
|
|
13065
13067
|
});
|
|
13066
13068
|
}
|
|
13067
|
-
|
|
13069
|
+
ngOnStop() {
|
|
13068
13070
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13069
|
-
|
|
13070
|
-
|
|
13071
|
+
const hadAuthToken = this._cache.authToken && true;
|
|
13072
|
+
const hadAuthBasic = this._cache.authBasic && true;
|
|
13073
|
+
const hadAuth = hadAuthToken || hadAuthBasic;
|
|
13074
|
+
this.resetData();
|
|
13075
|
+
if (hadAuth) {
|
|
13076
|
+
this.onLogout.next();
|
|
13077
|
+
this.onChange.next(undefined);
|
|
13078
|
+
if (hadAuthToken)
|
|
13079
|
+
this.onAuthTokenChange.next(undefined);
|
|
13080
|
+
if (hadAuthBasic)
|
|
13081
|
+
this.onAuthBasicChange.next(undefined);
|
|
13082
|
+
}
|
|
13071
13083
|
});
|
|
13072
13084
|
}
|
|
13073
|
-
ready() {
|
|
13074
|
-
if (this._started)
|
|
13075
|
-
return Promise.resolve(this.account);
|
|
13076
|
-
return this.start();
|
|
13077
|
-
}
|
|
13078
13085
|
isLogin() {
|
|
13079
|
-
return !!(this.
|
|
13086
|
+
return !!(this._cache.pubkey && this._cache.loaded);
|
|
13080
13087
|
}
|
|
13081
13088
|
isAuth() {
|
|
13082
|
-
return !!(this.
|
|
13089
|
+
return !!(this._cache.pubkey && this._cache.keypair && this._cache.keypair.secretKey);
|
|
13083
13090
|
}
|
|
13084
13091
|
hasMinProfile(userProfile) {
|
|
13085
13092
|
// should be login, and status ENABLE or TEMPORARY
|
|
13086
|
-
if (!this._data
|
|
13087
|
-
(this._data.
|
|
13093
|
+
if (!this._data || !this._data.pubkey ||
|
|
13094
|
+
(this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY)) {
|
|
13088
13095
|
return false;
|
|
13089
13096
|
}
|
|
13090
|
-
return PersonUtils.hasUpperOrEqualsProfile(this._data.
|
|
13097
|
+
return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, userProfile);
|
|
13091
13098
|
}
|
|
13092
13099
|
hasExactProfile(label) {
|
|
13093
13100
|
// should be login, and status ENABLE or TEMPORARY
|
|
13094
|
-
if (!this._data
|
|
13095
|
-
(this._data.
|
|
13101
|
+
if (!this._data || !this._data.pubkey ||
|
|
13102
|
+
(this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY))
|
|
13096
13103
|
return false;
|
|
13097
|
-
return this._data.
|
|
13104
|
+
return this._data.profiles.some(profile => profile === label);
|
|
13098
13105
|
}
|
|
13099
13106
|
hasProfileAndIsEnable(userProfile) {
|
|
13100
13107
|
// should be login, and status ENABLE
|
|
13101
|
-
if (!this._data
|
|
13108
|
+
if (!this._data || !this._data.pubkey || this._data.statusId !== StatusIds.ENABLE)
|
|
13102
13109
|
return false;
|
|
13103
|
-
return PersonUtils.hasUpperOrEqualsProfile(this._data.
|
|
13110
|
+
return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, userProfile);
|
|
13104
13111
|
}
|
|
13105
13112
|
isAdmin() {
|
|
13106
13113
|
return this.hasProfileAndIsEnable('ADMIN');
|
|
@@ -13120,11 +13127,11 @@ class AccountService extends BaseGraphqlService {
|
|
|
13120
13127
|
}
|
|
13121
13128
|
isOnlyGuest() {
|
|
13122
13129
|
// Should be login, and status ENABLE or TEMPORARY
|
|
13123
|
-
if (!this._data
|
|
13124
|
-
(this._data.
|
|
13130
|
+
if (!this._data || !this._data.pubkey ||
|
|
13131
|
+
(this._data.statusId !== StatusIds.ENABLE && this._data.statusId !== StatusIds.TEMPORARY))
|
|
13125
13132
|
return false;
|
|
13126
13133
|
// Profile less then user
|
|
13127
|
-
return !PersonUtils.hasUpperOrEqualsProfile(this._data.
|
|
13134
|
+
return !PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, 'USER');
|
|
13128
13135
|
}
|
|
13129
13136
|
canUserWriteDataForDepartment(recorderDepartment) {
|
|
13130
13137
|
if (ReferentialUtils.isEmpty(recorderDepartment)) {
|
|
@@ -13133,17 +13140,17 @@ class AccountService extends BaseGraphqlService {
|
|
|
13133
13140
|
return this.isAdmin();
|
|
13134
13141
|
}
|
|
13135
13142
|
// Should be login, and status ENABLE
|
|
13136
|
-
if (!this._data
|
|
13143
|
+
if (!this._data || !this._data.pubkey || this._data.statusId !== StatusIds.ENABLE)
|
|
13137
13144
|
return false;
|
|
13138
|
-
if (!this._data.
|
|
13145
|
+
if (!this._data.department || !this._data.department.id) {
|
|
13139
13146
|
console.warn('User account has no department ! Unable to check write right against recorderDepartment');
|
|
13140
13147
|
return false;
|
|
13141
13148
|
}
|
|
13142
13149
|
// Same recorder department: OK, user can write
|
|
13143
|
-
if (this._data.
|
|
13150
|
+
if (this._data.department.id === recorderDepartment.id)
|
|
13144
13151
|
return true;
|
|
13145
13152
|
// Else, check if supervisor (or more)
|
|
13146
|
-
return PersonUtils.hasUpperOrEqualsProfile(this._data.
|
|
13153
|
+
return PersonUtils.hasUpperOrEqualsProfile(this._data.profiles, 'SUPERVISOR');
|
|
13147
13154
|
}
|
|
13148
13155
|
register(data) {
|
|
13149
13156
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -13154,7 +13161,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13154
13161
|
throw new Error('Missing required username or password');
|
|
13155
13162
|
if (this._debug)
|
|
13156
13163
|
console.debug('[account] Register new user account...', data.account);
|
|
13157
|
-
this.
|
|
13164
|
+
this._cache.loaded = false;
|
|
13158
13165
|
const now = Date.now();
|
|
13159
13166
|
try {
|
|
13160
13167
|
const keypair = yield this.cryptoService.scryptKeypair(data.username, data.password);
|
|
@@ -13164,22 +13171,22 @@ class AccountService extends BaseGraphqlService {
|
|
|
13164
13171
|
data.account.settings.locale = this.settings.locale;
|
|
13165
13172
|
data.account.settings.latLongFormat = this.settings.latLongFormat;
|
|
13166
13173
|
data.account.department.id = data.account.department.id || this.environment.defaultDepartmentId;
|
|
13167
|
-
this.
|
|
13174
|
+
this._cache.keypair = keypair;
|
|
13168
13175
|
const account = yield this.saveRemotely(data.account, keypair);
|
|
13169
13176
|
// Default values
|
|
13170
13177
|
account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);
|
|
13171
|
-
this.
|
|
13172
|
-
this._data
|
|
13173
|
-
this.
|
|
13178
|
+
this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
13179
|
+
this._data = account;
|
|
13180
|
+
this._cache.pubkey = account.pubkey;
|
|
13174
13181
|
// Try to auth on pod
|
|
13175
13182
|
yield this.authenticate(data);
|
|
13176
|
-
this.
|
|
13183
|
+
this._cache.loaded = true;
|
|
13177
13184
|
yield this.saveLocally();
|
|
13178
13185
|
console.debug(`[account] Account successfully registered in ${Date.now() - now}ms`);
|
|
13179
13186
|
// Emit events
|
|
13180
|
-
this.onLogin.next(this._data
|
|
13181
|
-
this.onChange.next(this._data
|
|
13182
|
-
return this._data
|
|
13187
|
+
this.onLogin.next(this._data);
|
|
13188
|
+
this.onChange.next(this._data);
|
|
13189
|
+
return this._data;
|
|
13183
13190
|
}
|
|
13184
13191
|
catch (error) {
|
|
13185
13192
|
console.error(error && error.message || error);
|
|
@@ -13195,20 +13202,20 @@ class AccountService extends BaseGraphqlService {
|
|
|
13195
13202
|
// Basic auth
|
|
13196
13203
|
if (tokenType === 'basic' || tokenType === 'basic-and-token') {
|
|
13197
13204
|
// Generate the authBasic, if used
|
|
13198
|
-
if (!this.
|
|
13205
|
+
if (!this._cache.authBasic) {
|
|
13199
13206
|
// Skip if token already provided
|
|
13200
|
-
if (!(this.
|
|
13207
|
+
if (!(this._cache.authToken && tokenType === 'basic-and-token')) {
|
|
13201
13208
|
if (!data || !data.username || !data.password)
|
|
13202
13209
|
throw new Error('Missing username and password');
|
|
13203
|
-
this.
|
|
13210
|
+
this._cache.authBasic = this.cryptoService.encodeBase64(`${data.username}:${data.password}`);
|
|
13204
13211
|
}
|
|
13205
13212
|
}
|
|
13206
|
-
this.onAuthBasicChange.next(this.
|
|
13213
|
+
this.onAuthBasicChange.next(this._cache.authBasic);
|
|
13207
13214
|
}
|
|
13208
13215
|
// Generate the authToken, if used
|
|
13209
13216
|
if (tokenType === 'token' || tokenType === 'basic-and-token') {
|
|
13210
13217
|
try {
|
|
13211
|
-
this.
|
|
13218
|
+
this._cache.authToken = yield this.authenticateAndGetToken(this._cache.authToken);
|
|
13212
13219
|
}
|
|
13213
13220
|
catch (error) {
|
|
13214
13221
|
// Never authenticate, or not ready for offline mode => exit
|
|
@@ -13219,7 +13226,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13219
13226
|
}
|
|
13220
13227
|
// Forget authBasic, to switch to authToken
|
|
13221
13228
|
if (tokenType === 'basic-and-token') {
|
|
13222
|
-
this.
|
|
13229
|
+
this._cache.authBasic = undefined;
|
|
13223
13230
|
this.onAuthBasicChange.next(undefined);
|
|
13224
13231
|
}
|
|
13225
13232
|
});
|
|
@@ -13239,18 +13246,18 @@ class AccountService extends BaseGraphqlService {
|
|
|
13239
13246
|
throw { code: ErrorCodes$2.UNKNOWN_ERROR, message: 'ERROR.SCRYPT_ERROR' };
|
|
13240
13247
|
}
|
|
13241
13248
|
// Store pubkey+keypair
|
|
13242
|
-
this.
|
|
13243
|
-
this.
|
|
13249
|
+
this._cache.pubkey = Base58.encode(keypair.publicKey);
|
|
13250
|
+
this._cache.keypair = keypair;
|
|
13244
13251
|
// Try to load previous token
|
|
13245
13252
|
let previousToken = yield this.storage.get(TOKEN_STORAGE_KEY);
|
|
13246
|
-
previousToken = previousToken && previousToken.startsWith(this.
|
|
13253
|
+
previousToken = previousToken && previousToken.startsWith(this._cache.pubkey) && previousToken || null;
|
|
13247
13254
|
// Offline mode
|
|
13248
13255
|
const offline = this.settings.hasOfflineFeature() && (this.network.offline || data.offline === true);
|
|
13249
13256
|
if (offline) {
|
|
13250
|
-
this.
|
|
13257
|
+
this._cache.authToken = previousToken;
|
|
13251
13258
|
// Make sure network if set as offline
|
|
13252
13259
|
this.network.setForceOffline(true, { showToast: false });
|
|
13253
|
-
console.info(`[account] Login [OK] {pubkey: ${this.
|
|
13260
|
+
console.info(`[account] Login [OK] {pubkey: ${this._cache.pubkey.substr(0, 8)}}, {offline: true}`);
|
|
13254
13261
|
}
|
|
13255
13262
|
// Online mode: try to auth on pod
|
|
13256
13263
|
else {
|
|
@@ -13300,14 +13307,14 @@ class AccountService extends BaseGraphqlService {
|
|
|
13300
13307
|
throw error;
|
|
13301
13308
|
}
|
|
13302
13309
|
// Emit event to observers
|
|
13303
|
-
this.onLogin.next(this._data
|
|
13304
|
-
this.onChange.next(this._data
|
|
13305
|
-
return this._data
|
|
13310
|
+
this.onLogin.next(this._data);
|
|
13311
|
+
this.onChange.next(this._data);
|
|
13312
|
+
return this._data;
|
|
13306
13313
|
});
|
|
13307
13314
|
}
|
|
13308
13315
|
refresh() {
|
|
13309
13316
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13310
|
-
if (!this.
|
|
13317
|
+
if (!this._cache.pubkey)
|
|
13311
13318
|
throw new Error('User not logged');
|
|
13312
13319
|
if (this.network.offline)
|
|
13313
13320
|
throw new Error('Cannot check account in offline mode');
|
|
@@ -13315,9 +13322,9 @@ class AccountService extends BaseGraphqlService {
|
|
|
13315
13322
|
yield this.saveLocally();
|
|
13316
13323
|
console.debug('[account] Successfully reload account');
|
|
13317
13324
|
// Emit login event to subscribers
|
|
13318
|
-
this.onLogin.next(this._data
|
|
13319
|
-
this.onChange.next(this._data
|
|
13320
|
-
return this._data
|
|
13325
|
+
this.onLogin.next(this._data);
|
|
13326
|
+
this.onChange.next(this._data);
|
|
13327
|
+
return this._data;
|
|
13321
13328
|
});
|
|
13322
13329
|
}
|
|
13323
13330
|
/**
|
|
@@ -13327,29 +13334,29 @@ class AccountService extends BaseGraphqlService {
|
|
|
13327
13334
|
*/
|
|
13328
13335
|
save(account) {
|
|
13329
13336
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13330
|
-
if (!this.
|
|
13337
|
+
if (!this._cache.pubkey)
|
|
13331
13338
|
return Promise.reject('User not logged');
|
|
13332
|
-
if (this.
|
|
13339
|
+
if (this._cache.pubkey !== account.pubkey)
|
|
13333
13340
|
return Promise.reject('Not user account');
|
|
13334
|
-
account = yield this.saveRemotely(account, this.
|
|
13341
|
+
account = yield this.saveRemotely(account, this._cache.keypair);
|
|
13335
13342
|
// Set defaults
|
|
13336
13343
|
account.avatar = account.avatar || (this.environment.baseUrl + DEFAULT_AVATAR_IMAGE);
|
|
13337
|
-
this.
|
|
13338
|
-
this._data
|
|
13339
|
-
this.
|
|
13344
|
+
this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
13345
|
+
this._data = account;
|
|
13346
|
+
this._cache.loaded = true;
|
|
13340
13347
|
// Save locally (in storage)
|
|
13341
13348
|
yield this.saveLocally();
|
|
13342
13349
|
// Send event
|
|
13343
|
-
this.onLogin.next(this._data
|
|
13344
|
-
this.onChange.next(this._data
|
|
13345
|
-
return this._data
|
|
13350
|
+
this.onLogin.next(this._data);
|
|
13351
|
+
this.onChange.next(this._data);
|
|
13352
|
+
return this._data;
|
|
13346
13353
|
});
|
|
13347
13354
|
}
|
|
13348
13355
|
logout() {
|
|
13349
13356
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13350
|
-
const hadAuthToken = this.
|
|
13351
|
-
const hadAuthBasic = this.
|
|
13352
|
-
const pubkey = this.
|
|
13357
|
+
const hadAuthToken = this._cache.authToken && true;
|
|
13358
|
+
const hadAuthBasic = this._cache.authBasic && true;
|
|
13359
|
+
const pubkey = this._cache && this._cache.pubkey;
|
|
13353
13360
|
this.resetData();
|
|
13354
13361
|
if (!this.settings.hasOfflineFeature()) {
|
|
13355
13362
|
// Remove all data from the local storage
|
|
@@ -13402,9 +13409,9 @@ class AccountService extends BaseGraphqlService {
|
|
|
13402
13409
|
if (offline) {
|
|
13403
13410
|
json = yield this.storage.get(ACCOUNT_STORAGE_KEY);
|
|
13404
13411
|
json = json && (typeof json === 'string') && JSON.parse(json) || json;
|
|
13405
|
-
json = json && this.
|
|
13406
|
-
if (!json && this.
|
|
13407
|
-
json = yield this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this.
|
|
13412
|
+
json = json && this._cache.pubkey && (json.pubkey === this._cache.pubkey) && json || null;
|
|
13413
|
+
if (!json && this._cache.pubkey) {
|
|
13414
|
+
json = yield this.storage.get(ACCOUNT_STORAGE_KEY + '#' + this._cache.pubkey);
|
|
13408
13415
|
json = json && (typeof json === 'string') && JSON.parse(json) || json;
|
|
13409
13416
|
}
|
|
13410
13417
|
}
|
|
@@ -13499,7 +13506,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13499
13506
|
});
|
|
13500
13507
|
}
|
|
13501
13508
|
listenChanges() {
|
|
13502
|
-
if (!this.
|
|
13509
|
+
if (!this._cache.pubkey)
|
|
13503
13510
|
return Subscription.EMPTY;
|
|
13504
13511
|
const self = this;
|
|
13505
13512
|
console.debug('[account] [WS] Listening account changes');
|
|
@@ -13517,7 +13524,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13517
13524
|
var _a;
|
|
13518
13525
|
if (!data)
|
|
13519
13526
|
return;
|
|
13520
|
-
const existingUpdateDate = toDateISOString((_a = self._data
|
|
13527
|
+
const existingUpdateDate = toDateISOString((_a = self._data) === null || _a === void 0 ? void 0 : _a.updateDate);
|
|
13521
13528
|
if (existingUpdateDate !== data.updateDate) {
|
|
13522
13529
|
console.debug(`[account] [WS] Detected update on {${data.updateDate}}`);
|
|
13523
13530
|
yield self.refresh();
|
|
@@ -13544,20 +13551,6 @@ class AccountService extends BaseGraphqlService {
|
|
|
13544
13551
|
subscription.add(() => console.debug('[account] [WS] Stop listening account changes'));
|
|
13545
13552
|
return subscription;
|
|
13546
13553
|
}
|
|
13547
|
-
/**
|
|
13548
|
-
* @deprecated
|
|
13549
|
-
*/
|
|
13550
|
-
getPageSettings(pageId, propertyName) {
|
|
13551
|
-
return this.settings.getPageSettings(pageId, propertyName);
|
|
13552
|
-
}
|
|
13553
|
-
/**
|
|
13554
|
-
* @deprecated
|
|
13555
|
-
*/
|
|
13556
|
-
savePageSetting(pageId, value, propertyName) {
|
|
13557
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
13558
|
-
yield this.settings.savePageSetting(pageId, value, propertyName);
|
|
13559
|
-
});
|
|
13560
|
-
}
|
|
13561
13554
|
get additionalFields() {
|
|
13562
13555
|
return this._$additionalFields.getValue();
|
|
13563
13556
|
}
|
|
@@ -13578,21 +13571,21 @@ class AccountService extends BaseGraphqlService {
|
|
|
13578
13571
|
}
|
|
13579
13572
|
/* -- protected method -- */
|
|
13580
13573
|
resetData() {
|
|
13581
|
-
this.
|
|
13582
|
-
this.
|
|
13583
|
-
this.
|
|
13584
|
-
this.
|
|
13585
|
-
this.
|
|
13586
|
-
this.
|
|
13587
|
-
this.
|
|
13588
|
-
this.
|
|
13589
|
-
this._data
|
|
13574
|
+
this._cache.loaded = false;
|
|
13575
|
+
this._cache.keypair = null;
|
|
13576
|
+
this._cache.authToken = null;
|
|
13577
|
+
this._cache.authBasic = null;
|
|
13578
|
+
this._cache.pubkey = null;
|
|
13579
|
+
this._cache.mainProfile = null;
|
|
13580
|
+
this._cache.person = null;
|
|
13581
|
+
this._cache.department = null;
|
|
13582
|
+
this._data = new Account();
|
|
13590
13583
|
}
|
|
13591
13584
|
loadData(opts) {
|
|
13592
13585
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13593
|
-
if (!this.
|
|
13586
|
+
if (!this._cache.pubkey)
|
|
13594
13587
|
throw new Error('User not logged');
|
|
13595
|
-
this.
|
|
13588
|
+
this._cache.loaded = false;
|
|
13596
13589
|
try {
|
|
13597
13590
|
const account = (yield this.load(opts)) || new Account();
|
|
13598
13591
|
// Set defaults
|
|
@@ -13600,17 +13593,25 @@ class AccountService extends BaseGraphqlService {
|
|
|
13600
13593
|
account.settings = account.settings || new UserSettings();
|
|
13601
13594
|
account.settings.locale = account.settings.locale || this.settings.locale;
|
|
13602
13595
|
account.settings.latLongFormat = account.settings.latLongFormat || this.settings.latLongFormat || 'DDMM';
|
|
13596
|
+
account.settings.content = account.settings.content || {};
|
|
13603
13597
|
// Read main profile
|
|
13604
|
-
this.
|
|
13598
|
+
this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
13605
13599
|
// Update, instead of replace it
|
|
13606
|
-
if (this._data
|
|
13607
|
-
this._data.
|
|
13600
|
+
if (this._data) {
|
|
13601
|
+
this._data.fromObject(account);
|
|
13608
13602
|
}
|
|
13609
13603
|
else {
|
|
13610
|
-
this._data
|
|
13604
|
+
this._data = account;
|
|
13605
|
+
}
|
|
13606
|
+
this._cache.loaded = true;
|
|
13607
|
+
// Apply settings properties, found in remote settings
|
|
13608
|
+
const accountSettingsContentKeys = Object.keys(account.settings.content);
|
|
13609
|
+
if (isNotEmptyArray(accountSettingsContentKeys)) {
|
|
13610
|
+
const settings = Object.assign(Object.assign(Object.assign({}, this.settings.settings), account.settings.content), account.settings);
|
|
13611
|
+
delete settings.content; // Remove content attribute
|
|
13612
|
+
yield this.settings.apply(settings);
|
|
13611
13613
|
}
|
|
13612
|
-
this._data
|
|
13613
|
-
return this._data.account;
|
|
13614
|
+
return this._data;
|
|
13614
13615
|
}
|
|
13615
13616
|
catch (error) {
|
|
13616
13617
|
this.resetData();
|
|
@@ -13624,6 +13625,14 @@ class AccountService extends BaseGraphqlService {
|
|
|
13624
13625
|
}
|
|
13625
13626
|
});
|
|
13626
13627
|
}
|
|
13628
|
+
listenSettings() {
|
|
13629
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
13630
|
+
// When settings changed: save it remotely
|
|
13631
|
+
this.registerSubscription(this.settings.onChange
|
|
13632
|
+
.pipe(debounceTime(1000), filter(() => this.isLogin() && this.network.online))
|
|
13633
|
+
.subscribe(settings => this.saveLocalSettingsRemotely(settings)));
|
|
13634
|
+
});
|
|
13635
|
+
}
|
|
13627
13636
|
restoreLocally() {
|
|
13628
13637
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13629
13638
|
// Restore from storage
|
|
@@ -13644,9 +13653,9 @@ class AccountService extends BaseGraphqlService {
|
|
|
13644
13653
|
return;
|
|
13645
13654
|
if (this._debug)
|
|
13646
13655
|
console.debug(`[account] Account restoration...`);
|
|
13647
|
-
this.
|
|
13648
|
-
this.
|
|
13649
|
-
this.
|
|
13656
|
+
this._cache.authToken = token;
|
|
13657
|
+
this._cache.pubkey = pubkey;
|
|
13658
|
+
this._cache.keypair = seckey && {
|
|
13650
13659
|
publicKey: Base58.decode(pubkey),
|
|
13651
13660
|
secretKey: Base58.decode(seckey)
|
|
13652
13661
|
} || null;
|
|
@@ -13654,7 +13663,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13654
13663
|
if (this.network.online) {
|
|
13655
13664
|
try {
|
|
13656
13665
|
yield this.authenticate();
|
|
13657
|
-
if (!this.
|
|
13666
|
+
if (!this._cache.authToken && !this._cache.authBasic)
|
|
13658
13667
|
throw new Error('Authentication failed');
|
|
13659
13668
|
}
|
|
13660
13669
|
catch (error) {
|
|
@@ -13685,14 +13694,14 @@ class AccountService extends BaseGraphqlService {
|
|
|
13685
13694
|
// Transform to entity
|
|
13686
13695
|
const account = Account.fromObject(jsonAccount);
|
|
13687
13696
|
// Update data
|
|
13688
|
-
this._data
|
|
13689
|
-
this.
|
|
13690
|
-
this.
|
|
13697
|
+
this._data = account;
|
|
13698
|
+
this._cache.mainProfile = PersonUtils.getMainProfile(account.profiles);
|
|
13699
|
+
this._cache.loaded = true;
|
|
13691
13700
|
// Emit event
|
|
13692
|
-
this.onLogin.next(this._data
|
|
13693
|
-
this.onChange.next(this._data
|
|
13701
|
+
this.onLogin.next(this._data);
|
|
13702
|
+
this.onChange.next(this._data);
|
|
13694
13703
|
if (this._debug)
|
|
13695
|
-
console.debug(`[account] Account restoration [OK] {pubkey: ${pubkey.substr(0, 8)}}, {profile: ${this.
|
|
13704
|
+
console.debug(`[account] Account restoration [OK] {pubkey: ${pubkey.substr(0, 8)}}, {profile: ${this._cache.mainProfile}}`);
|
|
13696
13705
|
return account;
|
|
13697
13706
|
});
|
|
13698
13707
|
}
|
|
@@ -13701,13 +13710,13 @@ class AccountService extends BaseGraphqlService {
|
|
|
13701
13710
|
*/
|
|
13702
13711
|
saveLocally() {
|
|
13703
13712
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13704
|
-
if (!this.
|
|
13713
|
+
if (!this._cache.pubkey)
|
|
13705
13714
|
throw new Error('User not logged');
|
|
13706
13715
|
if (this._debug)
|
|
13707
|
-
console.debug(`[account] Saving account {${this.
|
|
13716
|
+
console.debug(`[account] Saving account {${this._cache.pubkey.substring(0, 6)}} in local storage...`);
|
|
13708
13717
|
// Convert account to json
|
|
13709
|
-
const json = this._data.
|
|
13710
|
-
const seckey = this.
|
|
13718
|
+
const json = this._data.asObject({ keepTypename: true });
|
|
13719
|
+
const seckey = this._cache.keypair && this._cache.keypair.secretKey && Base58.encode(this._cache.keypair.secretKey) || null;
|
|
13711
13720
|
// Convert avatar URL to dataUrl (e.g. 'data:image/png:<base64 content>')
|
|
13712
13721
|
const hasAvatarUrl = json.avatar && !json.avatar.endsWith(DEFAULT_AVATAR_IMAGE) &&
|
|
13713
13722
|
(json.avatar.startsWith('http://') || (json.avatar.startsWith('https://')));
|
|
@@ -13728,9 +13737,9 @@ class AccountService extends BaseGraphqlService {
|
|
|
13728
13737
|
}
|
|
13729
13738
|
try {
|
|
13730
13739
|
yield Promise.all([
|
|
13731
|
-
this.storage.set(PUBKEY_STORAGE_KEY, this.
|
|
13732
|
-
this.storage.set(TOKEN_STORAGE_KEY, this.
|
|
13733
|
-
this.storage.set(`${ACCOUNT_STORAGE_KEY}#${this.
|
|
13740
|
+
this.storage.set(PUBKEY_STORAGE_KEY, this._cache.pubkey),
|
|
13741
|
+
this.storage.set(TOKEN_STORAGE_KEY, this._cache.authToken),
|
|
13742
|
+
this.storage.set(`${ACCOUNT_STORAGE_KEY}#${this._cache.pubkey}`, json),
|
|
13734
13743
|
// Secret key (optional)
|
|
13735
13744
|
seckey && this.storage.set(SECKEY_STORAGE_KEY, seckey) || this.storage.remove(SECKEY_STORAGE_KEY),
|
|
13736
13745
|
// Remove old storage key
|
|
@@ -13744,6 +13753,22 @@ class AccountService extends BaseGraphqlService {
|
|
|
13744
13753
|
}
|
|
13745
13754
|
});
|
|
13746
13755
|
}
|
|
13756
|
+
saveLocalSettingsRemotely(source) {
|
|
13757
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
13758
|
+
if (!source || !this.isLogin())
|
|
13759
|
+
return; // Skip
|
|
13760
|
+
const account = this.account;
|
|
13761
|
+
// Merge local settings into account's settings
|
|
13762
|
+
const settings = UserSettings.fromObject(account.settings) || new UserSettings();
|
|
13763
|
+
const hasChanges = settings.merge(source, ['locale', 'latLongFormat', 'properties']);
|
|
13764
|
+
if (hasChanges) {
|
|
13765
|
+
if (this._debug)
|
|
13766
|
+
console.debug('[account] Save local settings remotely', settings);
|
|
13767
|
+
account.settings = settings;
|
|
13768
|
+
yield this.saveRemotely(account);
|
|
13769
|
+
}
|
|
13770
|
+
});
|
|
13771
|
+
}
|
|
13747
13772
|
/**
|
|
13748
13773
|
* Create or update an user account
|
|
13749
13774
|
*
|
|
@@ -13788,7 +13813,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13788
13813
|
}
|
|
13789
13814
|
authenticateAndGetToken(token, counter) {
|
|
13790
13815
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13791
|
-
if (!this.
|
|
13816
|
+
if (!this._cache.pubkey)
|
|
13792
13817
|
throw new Error('User not logged');
|
|
13793
13818
|
if (!counter)
|
|
13794
13819
|
console.info('[account] Authentication on pod...');
|
|
@@ -13814,7 +13839,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
13814
13839
|
if (data && data.authenticate) {
|
|
13815
13840
|
// Store the token
|
|
13816
13841
|
this.onAuthTokenChange.next(token);
|
|
13817
|
-
console.info(`[account] Authentication on pod [OK] {pubkey: '${this.
|
|
13842
|
+
console.info(`[account] Authentication on pod [OK] {pubkey: '${this._cache.pubkey.substr(0, 8)}'}`);
|
|
13818
13843
|
return token; // return the token
|
|
13819
13844
|
}
|
|
13820
13845
|
// Continue (will retry with another challenge)
|
|
@@ -13840,8 +13865,8 @@ class AccountService extends BaseGraphqlService {
|
|
|
13840
13865
|
}
|
|
13841
13866
|
// TODO: check server pubkey as a valid certificate
|
|
13842
13867
|
// Do the challenge
|
|
13843
|
-
const signature = yield this.cryptoService.sign(data.authChallenge.challenge, this.
|
|
13844
|
-
const newToken = `${this.
|
|
13868
|
+
const signature = yield this.cryptoService.sign(data.authChallenge.challenge, this._cache.keypair);
|
|
13869
|
+
const newToken = `${this._cache.pubkey}:${data.authChallenge.challenge}|${signature}`;
|
|
13845
13870
|
// iterate with the new token
|
|
13846
13871
|
return yield this.authenticateAndGetToken(newToken, (counter || 1) + 1 /* increment */);
|
|
13847
13872
|
});
|
|
@@ -14181,73 +14206,28 @@ class ConfigService extends BaseGraphqlService {
|
|
|
14181
14206
|
this.toastController = toastController;
|
|
14182
14207
|
this.translate = translate;
|
|
14183
14208
|
this.environment = environment;
|
|
14184
|
-
this._started = false;
|
|
14185
|
-
this._subscription = new Subscription();
|
|
14186
14209
|
this.$data = new BehaviorSubject(null);
|
|
14187
14210
|
this._debug = !environment.production;
|
|
14188
14211
|
if (this._debug)
|
|
14189
14212
|
console.debug('[config] Creating service');
|
|
14190
14213
|
this._optionDefs = Object.values(Object.assign(Object.assign({}, CORE_CONFIG_OPTIONS), defaultOptionsMap));
|
|
14191
|
-
// Restart if graphql service restart
|
|
14192
|
-
this.graphql.onStart.subscribe(() => this.restart());
|
|
14193
|
-
// Start
|
|
14194
|
-
if (this.graphql.started) {
|
|
14195
|
-
this.start();
|
|
14196
|
-
}
|
|
14197
|
-
}
|
|
14198
|
-
get started() {
|
|
14199
|
-
return this._started;
|
|
14200
14214
|
}
|
|
14201
14215
|
get config() {
|
|
14202
14216
|
// If first call: start loading
|
|
14203
|
-
if (!this.
|
|
14217
|
+
if (!this.started)
|
|
14204
14218
|
this.start();
|
|
14205
14219
|
return this.$data.pipe(filter(isNotNil));
|
|
14206
14220
|
}
|
|
14207
|
-
|
|
14208
|
-
|
|
14209
|
-
|
|
14210
|
-
|
|
14211
|
-
return;
|
|
14212
|
-
console.info('[config] Starting configuration...');
|
|
14213
|
-
this._startPromise = this.graphql.ready()
|
|
14214
|
-
.then(() => this.loadOrRestoreLocally())
|
|
14215
|
-
.then((data) => {
|
|
14216
|
-
this._started = true;
|
|
14217
|
-
this._startPromise = undefined;
|
|
14221
|
+
ngOnStart() {
|
|
14222
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14223
|
+
console.info('[config] Starting configuration...');
|
|
14224
|
+
const data = yield this.loadOrRestoreLocally();
|
|
14218
14225
|
this.$data.next(data);
|
|
14226
|
+
// Restart if graphql service restart
|
|
14227
|
+
this.registerSubscription(this.graphql.onStart.subscribe(() => this.restart()));
|
|
14219
14228
|
return data;
|
|
14220
|
-
})
|
|
14221
|
-
.catch((err) => {
|
|
14222
|
-
console.error(err && err.message || err, err);
|
|
14223
|
-
this._started = false;
|
|
14224
|
-
this._startPromise = undefined;
|
|
14225
|
-
return null;
|
|
14226
|
-
});
|
|
14227
|
-
return this._startPromise;
|
|
14228
|
-
}
|
|
14229
|
-
stop() {
|
|
14230
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
14231
|
-
this._subscription.unsubscribe();
|
|
14232
|
-
this._subscription = new Subscription();
|
|
14233
|
-
this._started = false;
|
|
14234
|
-
this._startPromise = undefined;
|
|
14235
|
-
});
|
|
14236
|
-
}
|
|
14237
|
-
restart() {
|
|
14238
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
14239
|
-
if (this.started)
|
|
14240
|
-
yield this.stop();
|
|
14241
|
-
return this.start();
|
|
14242
14229
|
});
|
|
14243
14230
|
}
|
|
14244
|
-
ready() {
|
|
14245
|
-
if (this._started)
|
|
14246
|
-
return Promise.resolve(this.$data.value);
|
|
14247
|
-
if (this._startPromise)
|
|
14248
|
-
return this._startPromise;
|
|
14249
|
-
return this.start();
|
|
14250
|
-
}
|
|
14251
14231
|
loadDefault(opts) {
|
|
14252
14232
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14253
14233
|
const now = Date.now();
|
|
@@ -19755,12 +19735,6 @@ class BaseEntityService extends BaseGraphqlService {
|
|
|
19755
19735
|
this.defaultSortBy = options.defaultSortBy || 'id';
|
|
19756
19736
|
this.defaultSortDirection = options.defaultSortDirection || 'asc';
|
|
19757
19737
|
this.watchQueriesUpdatePolicy = options.watchQueriesUpdatePolicy || 'update-cache';
|
|
19758
|
-
platform.ready().then(() => {
|
|
19759
|
-
// No limit for updatable watch queries, if desktop
|
|
19760
|
-
if (!platform.mobile) {
|
|
19761
|
-
this._mutableWatchQueriesMaxCount = -1;
|
|
19762
|
-
}
|
|
19763
|
-
});
|
|
19764
19738
|
const obj = new dataType();
|
|
19765
19739
|
this._typename = obj.__typename || 'UnknownVO';
|
|
19766
19740
|
this._logTypeName = removeEnd(this._typename, 'VO');
|
|
@@ -20138,6 +20112,14 @@ class BaseEntityService extends BaseGraphqlService {
|
|
|
20138
20112
|
return EntityFilterUtils.fromObject(source, this.filterType);
|
|
20139
20113
|
}
|
|
20140
20114
|
/* -- protected functions -- */
|
|
20115
|
+
ngOnStart() {
|
|
20116
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20117
|
+
// No limit for updatable watch queries, if desktop
|
|
20118
|
+
if (!this.platform.mobile) {
|
|
20119
|
+
this._mutableWatchQueriesMaxCount = -1;
|
|
20120
|
+
}
|
|
20121
|
+
});
|
|
20122
|
+
}
|
|
20141
20123
|
fillDefaultProperties(source) {
|
|
20142
20124
|
// Can be override by subclasses
|
|
20143
20125
|
}
|