@sumaris-net/ngx-components 21.0.0-rc6 → 21.0.0-rc7
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/doc/changelog.md +4 -0
- package/fesm2022/sumaris-net-ngx-components-testing.mjs +496 -0
- package/fesm2022/sumaris-net-ngx-components-testing.mjs.map +1 -0
- package/fesm2022/sumaris-net.ngx-components.mjs +302 -137
- package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
- package/package.json +6 -1
- package/src/assets/manifest.json +1 -1
- package/types/sumaris-net-ngx-components-testing.d.ts +286 -0
- package/types/sumaris-net.ngx-components.d.ts +25 -2
|
@@ -226,6 +226,9 @@ class Environment {
|
|
|
226
226
|
// Default authentication /!\ For DEV only
|
|
227
227
|
// (see values in the test database - XML files in Pod's module)
|
|
228
228
|
defaultAuthValues;
|
|
229
|
+
// Auto login /!\ For DEV only
|
|
230
|
+
// (the order defines the method precedence)
|
|
231
|
+
startupOrder;
|
|
229
232
|
// Account
|
|
230
233
|
account;
|
|
231
234
|
entityEditor;
|
|
@@ -16479,138 +16482,6 @@ const StorageDrivers = {
|
|
|
16479
16482
|
};
|
|
16480
16483
|
const APP_STORAGE = new InjectionToken('Storage');
|
|
16481
16484
|
|
|
16482
|
-
// This file can be replaced during build by using the `fileReplacements` array.
|
|
16483
|
-
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
|
|
16484
|
-
// The list of file replacements can be found in `angular.json`.
|
|
16485
|
-
/*
|
|
16486
|
-
* In development mode, to ignore zone related error stack frames such as
|
|
16487
|
-
* `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
|
|
16488
|
-
* import the following file, but please comment it out in production mode
|
|
16489
|
-
* because it will have performance impact when throw error
|
|
16490
|
-
*/
|
|
16491
|
-
//import 'zone.js/plugins/zone-error';
|
|
16492
|
-
const environment = Object.freeze({
|
|
16493
|
-
name: '@sumaris-net/ngx-components', // overridden by ENVIRONMENT token
|
|
16494
|
-
version: '1.0', // overridden by ENVIRONMENT token
|
|
16495
|
-
// Do NOT set to false - because this value will be used by releases
|
|
16496
|
-
//production: false,
|
|
16497
|
-
production: true,
|
|
16498
|
-
// Do NOT set - because this value will be used by releases
|
|
16499
|
-
//externalEnvironmentUrl: null,
|
|
16500
|
-
baseUrl: '/',
|
|
16501
|
-
defaultLocale: 'fr',
|
|
16502
|
-
defaultLatLongFormat: 'DDMM',
|
|
16503
|
-
apolloFetchPolicy: 'cache-first',
|
|
16504
|
-
useHash: false,
|
|
16505
|
-
allowDarkMode: true,
|
|
16506
|
-
//defaultRoute: '/home',
|
|
16507
|
-
//enableMenu: true,
|
|
16508
|
-
// FIXME: enable cache
|
|
16509
|
-
persistCache: false,
|
|
16510
|
-
// TODO: make this works
|
|
16511
|
-
//offline: true,
|
|
16512
|
-
peerMinVersion: '1.8.0',
|
|
16513
|
-
peerDefaultPrefix: 'http://',
|
|
16514
|
-
enableSelectPeerByFeature: true,
|
|
16515
|
-
sendAppVersionHeaders: true,
|
|
16516
|
-
defaultPeer: {
|
|
16517
|
-
host: 'localhost',
|
|
16518
|
-
port: 8081,
|
|
16519
|
-
},
|
|
16520
|
-
defaultPeers: [
|
|
16521
|
-
{
|
|
16522
|
-
host: 'localhost',
|
|
16523
|
-
port: 8080,
|
|
16524
|
-
},
|
|
16525
|
-
{
|
|
16526
|
-
host: 'localhost',
|
|
16527
|
-
port: 8081,
|
|
16528
|
-
},
|
|
16529
|
-
{
|
|
16530
|
-
host: '192.168.0.45',
|
|
16531
|
-
port: 8080,
|
|
16532
|
-
},
|
|
16533
|
-
{
|
|
16534
|
-
host: '192.168.0.24',
|
|
16535
|
-
port: 8080,
|
|
16536
|
-
},
|
|
16537
|
-
{
|
|
16538
|
-
host: '192.168.0.29',
|
|
16539
|
-
port: 8080,
|
|
16540
|
-
},
|
|
16541
|
-
{
|
|
16542
|
-
host: '192.168.0.107',
|
|
16543
|
-
port: 8080,
|
|
16544
|
-
},
|
|
16545
|
-
{
|
|
16546
|
-
host: 'sih.sfa.sc',
|
|
16547
|
-
port: 443,
|
|
16548
|
-
},
|
|
16549
|
-
{
|
|
16550
|
-
host: 'test.sumaris.net',
|
|
16551
|
-
port: 443,
|
|
16552
|
-
},
|
|
16553
|
-
{
|
|
16554
|
-
host: 'open.sumaris.net',
|
|
16555
|
-
port: 443,
|
|
16556
|
-
},
|
|
16557
|
-
{
|
|
16558
|
-
host: 'server.e-is.pro',
|
|
16559
|
-
port: 443,
|
|
16560
|
-
},
|
|
16561
|
-
],
|
|
16562
|
-
defaultAppName: 'SUMARiS',
|
|
16563
|
-
defaultAndroidInstallUrl: 'https://play.google.com/store/apps/details?id=net.sumaris.app',
|
|
16564
|
-
defaultIOSInstallUrl: 'https://apps.apple.com/us/app/sumaris/id6736747523',
|
|
16565
|
-
defaultDesktopInstallUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/releases',
|
|
16566
|
-
// Storage
|
|
16567
|
-
storage: {
|
|
16568
|
-
driverOrder: [StorageDrivers.SQLLite, StorageDrivers.IndexedDB, StorageDrivers.WebSQL, StorageDrivers.LocalStorage],
|
|
16569
|
-
},
|
|
16570
|
-
// About
|
|
16571
|
-
sourceUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components',
|
|
16572
|
-
reportIssueUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/issues',
|
|
16573
|
-
forumUrl: null, //'https://forum.sumaris.net',
|
|
16574
|
-
helpUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/blob/master/user-manual/index_fr.md',
|
|
16575
|
-
privacyPolicyUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/raw/master/doc/privacy_policy_fr.md',
|
|
16576
|
-
termsOfUseUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/raw/master/doc/terms_of_use_fr.md?ref_type=heads',
|
|
16577
|
-
// Development
|
|
16578
|
-
defaultAuthValues: {
|
|
16579
|
-
// Token auth (using Person.pubkey)
|
|
16580
|
-
username: 'admin@sumaris.net',
|
|
16581
|
-
password: 'admin',
|
|
16582
|
-
},
|
|
16583
|
-
account: {
|
|
16584
|
-
enableListenChanges: true,
|
|
16585
|
-
listenIntervalInSeconds: 60,
|
|
16586
|
-
enableAvatarEdit: true,
|
|
16587
|
-
},
|
|
16588
|
-
entityEditor: {
|
|
16589
|
-
enableListenChanges: true,
|
|
16590
|
-
listenIntervalInSeconds: 60,
|
|
16591
|
-
},
|
|
16592
|
-
feed: {
|
|
16593
|
-
jsonFeed: {
|
|
16594
|
-
fr: [
|
|
16595
|
-
'/api/feed.json',
|
|
16596
|
-
'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/raw/master/doc/feed/feed-fr.json',
|
|
16597
|
-
// Example with JsonFeed version 1 (and not 1.1)
|
|
16598
|
-
//'https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/feed-fr.json',
|
|
16599
|
-
// Example with discourse API :
|
|
16600
|
-
//'https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-fr-FR.json',
|
|
16601
|
-
],
|
|
16602
|
-
en: [
|
|
16603
|
-
'/api/feed.json',
|
|
16604
|
-
'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/raw/master/doc/feed/feed-en.json'
|
|
16605
|
-
],
|
|
16606
|
-
},
|
|
16607
|
-
maxContentLength: 1000,
|
|
16608
|
-
maxAgeInMonths: -1,
|
|
16609
|
-
maxCount: 3,
|
|
16610
|
-
},
|
|
16611
|
-
buildDate: new Date().toISOString(),
|
|
16612
|
-
});
|
|
16613
|
-
|
|
16614
16485
|
class StorageService extends StartableService {
|
|
16615
16486
|
storage;
|
|
16616
16487
|
environment;
|
|
@@ -16626,7 +16497,7 @@ class StorageService extends StartableService {
|
|
|
16626
16497
|
}
|
|
16627
16498
|
async ngOnStart() {
|
|
16628
16499
|
try {
|
|
16629
|
-
console.debug(`[storage] Starting... {driverOrder: ${environment.storage?.driverOrder}}`);
|
|
16500
|
+
console.debug(`[storage] Starting... {driverOrder: ${this.environment.storage?.driverOrder}}`);
|
|
16630
16501
|
// Define Cordova SQLLite driver
|
|
16631
16502
|
await this.storage.defineDriver(CordovaSQLiteDriver);
|
|
16632
16503
|
// Create the storage instance
|
|
@@ -17141,6 +17012,139 @@ function isOnFieldMode(value) {
|
|
|
17141
17012
|
}
|
|
17142
17013
|
const APP_LOCALES = new InjectionToken('locales');
|
|
17143
17014
|
|
|
17015
|
+
// This file can be replaced during build by using the `fileReplacements` array.
|
|
17016
|
+
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
|
|
17017
|
+
// The list of file replacements can be found in `angular.json`.
|
|
17018
|
+
/*
|
|
17019
|
+
* In development mode, to ignore zone related error stack frames such as
|
|
17020
|
+
* `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
|
|
17021
|
+
* import the following file, but please comment it out in production mode
|
|
17022
|
+
* because it will have performance impact when throw error
|
|
17023
|
+
*/
|
|
17024
|
+
//import 'zone.js/plugins/zone-error';
|
|
17025
|
+
const environment = Object.freeze({
|
|
17026
|
+
name: '@sumaris-net/ngx-components', // overridden by ENVIRONMENT token
|
|
17027
|
+
version: '21.0.0-rc1', // overridden by ENVIRONMENT token
|
|
17028
|
+
// Do NOT set to false - because this value will be used by releases
|
|
17029
|
+
//production: false,
|
|
17030
|
+
production: true,
|
|
17031
|
+
// Do NOT set - because this value will be used by releases
|
|
17032
|
+
//externalEnvironmentUrl: null,
|
|
17033
|
+
baseUrl: '/',
|
|
17034
|
+
defaultLocale: 'fr',
|
|
17035
|
+
defaultLatLongFormat: 'DDMM',
|
|
17036
|
+
apolloFetchPolicy: 'cache-first',
|
|
17037
|
+
useHash: false,
|
|
17038
|
+
allowDarkMode: true,
|
|
17039
|
+
//defaultRoute: '/home',
|
|
17040
|
+
//enableMenu: true,
|
|
17041
|
+
// FIXME: enable cache
|
|
17042
|
+
persistCache: false,
|
|
17043
|
+
// TODO: make this works
|
|
17044
|
+
//offline: true,
|
|
17045
|
+
peerMinVersion: '1.8.0',
|
|
17046
|
+
peerDefaultPrefix: 'http://',
|
|
17047
|
+
enableSelectPeerByFeature: true,
|
|
17048
|
+
sendAppVersionHeaders: true,
|
|
17049
|
+
defaultPeer: {
|
|
17050
|
+
host: 'localhost',
|
|
17051
|
+
port: 8081,
|
|
17052
|
+
},
|
|
17053
|
+
defaultPeers: [
|
|
17054
|
+
{
|
|
17055
|
+
host: 'localhost',
|
|
17056
|
+
port: 8080,
|
|
17057
|
+
},
|
|
17058
|
+
{
|
|
17059
|
+
host: 'localhost',
|
|
17060
|
+
port: 8081,
|
|
17061
|
+
},
|
|
17062
|
+
{
|
|
17063
|
+
host: '192.168.0.45',
|
|
17064
|
+
port: 8080,
|
|
17065
|
+
},
|
|
17066
|
+
{
|
|
17067
|
+
host: '192.168.0.24',
|
|
17068
|
+
port: 8080,
|
|
17069
|
+
},
|
|
17070
|
+
{
|
|
17071
|
+
host: '192.168.0.29',
|
|
17072
|
+
port: 8080,
|
|
17073
|
+
},
|
|
17074
|
+
{
|
|
17075
|
+
host: '192.168.0.107',
|
|
17076
|
+
port: 8080,
|
|
17077
|
+
},
|
|
17078
|
+
{
|
|
17079
|
+
host: 'sih.sfa.sc',
|
|
17080
|
+
port: 443,
|
|
17081
|
+
},
|
|
17082
|
+
{
|
|
17083
|
+
host: 'test.sumaris.net',
|
|
17084
|
+
port: 443,
|
|
17085
|
+
},
|
|
17086
|
+
{
|
|
17087
|
+
host: 'open.sumaris.net',
|
|
17088
|
+
port: 443,
|
|
17089
|
+
},
|
|
17090
|
+
{
|
|
17091
|
+
host: 'server.e-is.pro',
|
|
17092
|
+
port: 443,
|
|
17093
|
+
},
|
|
17094
|
+
],
|
|
17095
|
+
defaultAppName: 'SUMARiS',
|
|
17096
|
+
defaultAndroidInstallUrl: 'https://play.google.com/store/apps/details?id=net.sumaris.app',
|
|
17097
|
+
defaultIOSInstallUrl: 'https://apps.apple.com/us/app/sumaris/id6736747523',
|
|
17098
|
+
defaultDesktopInstallUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/releases',
|
|
17099
|
+
// Storage
|
|
17100
|
+
storage: {
|
|
17101
|
+
driverOrder: [StorageDrivers.SQLLite, StorageDrivers.IndexedDB, StorageDrivers.WebSQL, StorageDrivers.LocalStorage],
|
|
17102
|
+
},
|
|
17103
|
+
// About
|
|
17104
|
+
sourceUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components',
|
|
17105
|
+
reportIssueUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/issues',
|
|
17106
|
+
forumUrl: null, //'https://forum.sumaris.net',
|
|
17107
|
+
helpUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-doc/-/blob/master/user-manual/index_fr.md',
|
|
17108
|
+
privacyPolicyUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/raw/master/doc/privacy_policy_fr.md',
|
|
17109
|
+
termsOfUseUrl: 'https://gitlab.ifremer.fr/sih-public/sumaris/sumaris-app/-/raw/master/doc/terms_of_use_fr.md?ref_type=heads',
|
|
17110
|
+
// Development
|
|
17111
|
+
defaultAuthValues: {
|
|
17112
|
+
// Token auth (using Person.pubkey)
|
|
17113
|
+
username: 'admin@sumaris.net',
|
|
17114
|
+
password: 'admin',
|
|
17115
|
+
},
|
|
17116
|
+
startupOrder: ['url', 'window', 'environment'],
|
|
17117
|
+
account: {
|
|
17118
|
+
enableListenChanges: true,
|
|
17119
|
+
listenIntervalInSeconds: 60,
|
|
17120
|
+
enableAvatarEdit: true,
|
|
17121
|
+
},
|
|
17122
|
+
entityEditor: {
|
|
17123
|
+
enableListenChanges: true,
|
|
17124
|
+
listenIntervalInSeconds: 60,
|
|
17125
|
+
},
|
|
17126
|
+
feed: {
|
|
17127
|
+
jsonFeed: {
|
|
17128
|
+
fr: [
|
|
17129
|
+
'/api/feed.json',
|
|
17130
|
+
'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/raw/master/doc/feed/feed-fr.json',
|
|
17131
|
+
// Example with JsonFeed version 1 (and not 1.1)
|
|
17132
|
+
//'https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/feed-fr.json',
|
|
17133
|
+
// Example with discourse API :
|
|
17134
|
+
//'https://raw.githubusercontent.com/duniter/cesium/master/doc/feed/1.1/feed-fr-FR.json',
|
|
17135
|
+
],
|
|
17136
|
+
en: [
|
|
17137
|
+
'/api/feed.json',
|
|
17138
|
+
'https://gitlab.ifremer.fr/sih-public/sumaris/ngx-sumaris-components/-/raw/master/doc/feed/feed-en.json'
|
|
17139
|
+
],
|
|
17140
|
+
},
|
|
17141
|
+
maxContentLength: 1000,
|
|
17142
|
+
maxAgeInMonths: -1,
|
|
17143
|
+
maxCount: 3,
|
|
17144
|
+
},
|
|
17145
|
+
buildDate: new Date().toISOString(),
|
|
17146
|
+
});
|
|
17147
|
+
|
|
17144
17148
|
class EntityClasses {
|
|
17145
17149
|
static CLASSES_BY_NAME = new Map();
|
|
17146
17150
|
static register(typename, entityClass) {
|
|
@@ -23784,6 +23788,145 @@ class Base58 {
|
|
|
23784
23788
|
}
|
|
23785
23789
|
}
|
|
23786
23790
|
|
|
23791
|
+
// Standalone startup constants, with NO Angular DI dependency.
|
|
23792
|
+
// Kept separate from startup.service.ts so it can be safely imported by e2e tests
|
|
23793
|
+
// (Playwright's transpiler does not support Angular parameter decorators).
|
|
23794
|
+
// Key used to bridge auto-peer/login data across a version-check reload.
|
|
23795
|
+
// platform.service may reload the page via location.href = ..., which destroys both
|
|
23796
|
+
// URL params (hash/search) and the window object. sessionStorage survives same-tab
|
|
23797
|
+
// reloads, is tab-scoped, non-persistent (cleared on tab close), and not accessible
|
|
23798
|
+
// cross-origin — making it safe for transient credential bridging.
|
|
23799
|
+
const STARTUP_DATA_STORAGE_KEY = '__appStartupData';
|
|
23800
|
+
|
|
23801
|
+
class StartupService {
|
|
23802
|
+
_data = { password: null, username: null, offline: null, peerUrl: null };
|
|
23803
|
+
storage = inject(StorageService);
|
|
23804
|
+
environment = inject(ENVIRONMENT, { optional: true });
|
|
23805
|
+
get data() {
|
|
23806
|
+
return this._data;
|
|
23807
|
+
}
|
|
23808
|
+
set data(data) {
|
|
23809
|
+
if (isNotNilOrBlank(data.username))
|
|
23810
|
+
this._data.username = data.username;
|
|
23811
|
+
if (isNotNilOrBlank(data.password))
|
|
23812
|
+
this._data.password = data.password;
|
|
23813
|
+
if (isNotNil(data.offline))
|
|
23814
|
+
this._data.offline = data.offline;
|
|
23815
|
+
if (isNotNilOrBlank(data.peerUrl))
|
|
23816
|
+
this._data.peerUrl = data.peerUrl;
|
|
23817
|
+
}
|
|
23818
|
+
hasPeer() {
|
|
23819
|
+
return isNotNilOrBlank(this._data?.peerUrl);
|
|
23820
|
+
}
|
|
23821
|
+
consumePeer() {
|
|
23822
|
+
if (!this._data)
|
|
23823
|
+
return null;
|
|
23824
|
+
const autoPeer = this._data?.peerUrl;
|
|
23825
|
+
this._data.peerUrl = null;
|
|
23826
|
+
return autoPeer;
|
|
23827
|
+
}
|
|
23828
|
+
hasAuth() {
|
|
23829
|
+
return isNotNilOrBlank(this._data?.username) && isNotNilOrBlank(this._data?.password);
|
|
23830
|
+
}
|
|
23831
|
+
consumeAuth() {
|
|
23832
|
+
if (!this._data)
|
|
23833
|
+
return null;
|
|
23834
|
+
const { username, password, offline } = this._data;
|
|
23835
|
+
this._data.username = null;
|
|
23836
|
+
this._data.password = null;
|
|
23837
|
+
this._data.offline = null;
|
|
23838
|
+
return { username, password, offline };
|
|
23839
|
+
}
|
|
23840
|
+
async start() {
|
|
23841
|
+
const authMethods = this.environment?.startupOrder;
|
|
23842
|
+
if (isEmptyArray(authMethods))
|
|
23843
|
+
return; // Skip if no auth methods configured
|
|
23844
|
+
await this.storage.ready();
|
|
23845
|
+
console.debug(`[startup] Initializing methods: ${authMethods.join(' -> ')}`);
|
|
23846
|
+
const urlHashParams = new URLSearchParams(window.location.hash?.slice(1) || '');
|
|
23847
|
+
const urlSearchParams = new URLSearchParams(window.location.search);
|
|
23848
|
+
const windowStartupData = window[STARTUP_DATA_STORAGE_KEY];
|
|
23849
|
+
const rawData = sessionStorage.getItem(STARTUP_DATA_STORAGE_KEY);
|
|
23850
|
+
const data = rawData ? JSON.parse(rawData) : null;
|
|
23851
|
+
const settingsRaw = await this.storage.get('settings');
|
|
23852
|
+
const settings = typeof settingsRaw === 'string' ? JSON.parse(settingsRaw) : (settingsRaw ?? {});
|
|
23853
|
+
// Resolve auto auth data from each configured source
|
|
23854
|
+
if (data) {
|
|
23855
|
+
// Restore from sessionStorage in case of a previous version-check reload
|
|
23856
|
+
this.data = data;
|
|
23857
|
+
}
|
|
23858
|
+
else {
|
|
23859
|
+
// Resolve each configured source by priority (first method has highest priority)
|
|
23860
|
+
let username = null;
|
|
23861
|
+
let password = null;
|
|
23862
|
+
let offline = null;
|
|
23863
|
+
let peerUrl = null;
|
|
23864
|
+
for (const authMethod of authMethods.reverse()) {
|
|
23865
|
+
switch (authMethod) {
|
|
23866
|
+
case 'url':
|
|
23867
|
+
username = urlHashParams.get('username') || urlSearchParams.get('username');
|
|
23868
|
+
password = urlHashParams.get('password') || urlSearchParams.get('password');
|
|
23869
|
+
offline = urlHashParams.get('offline') === 'true' || urlSearchParams.get('offline') === 'true';
|
|
23870
|
+
peerUrl = urlHashParams.get('peerUrl') || urlSearchParams.get('peerUrl');
|
|
23871
|
+
break;
|
|
23872
|
+
case 'window':
|
|
23873
|
+
username = windowStartupData?.username ?? null;
|
|
23874
|
+
password = windowStartupData?.password ?? null;
|
|
23875
|
+
offline = windowStartupData?.offline ?? null;
|
|
23876
|
+
peerUrl = windowStartupData?.peerUrl ?? null;
|
|
23877
|
+
break;
|
|
23878
|
+
case 'environment':
|
|
23879
|
+
username = this.environment?.defaultAuthValues?.username;
|
|
23880
|
+
password = this.environment?.defaultAuthValues?.password;
|
|
23881
|
+
offline = this.environment?.offline;
|
|
23882
|
+
peerUrl = Peer.fromObject(this.environment?.peer)?.url ||
|
|
23883
|
+
settings?.peerUrl || Peer.fromObject(this.environment.defaultPeer)?.url;
|
|
23884
|
+
break;
|
|
23885
|
+
default:
|
|
23886
|
+
console.warn('[startup] Unknown method:', authMethod);
|
|
23887
|
+
}
|
|
23888
|
+
this.data = { username, password, offline, peerUrl };
|
|
23889
|
+
}
|
|
23890
|
+
}
|
|
23891
|
+
const sensitiveParams = ['username', 'password', 'offline', 'peerUrl'];
|
|
23892
|
+
const hasHashSensitiveParam = sensitiveParams.some((p) => urlHashParams.has(p));
|
|
23893
|
+
const hasSearchSensitiveParam = sensitiveParams.some((p) => urlSearchParams.has(p));
|
|
23894
|
+
const hasWindowData = !!windowStartupData;
|
|
23895
|
+
const hasExternalSource = hasHashSensitiveParam || hasSearchSensitiveParam || hasWindowData;
|
|
23896
|
+
// Persist to sessionStorage so data survives a potential version-check reload
|
|
23897
|
+
if (hasExternalSource && (this.hasPeer() || this.hasAuth())) {
|
|
23898
|
+
sessionStorage.setItem(STARTUP_DATA_STORAGE_KEY, JSON.stringify(this._data));
|
|
23899
|
+
}
|
|
23900
|
+
// Apply auto peer by saving peerUrl to localStorage so the app connects to the right peer
|
|
23901
|
+
if (this.hasPeer()) {
|
|
23902
|
+
settings.peerUrl = this.consumePeer();
|
|
23903
|
+
console.debug(`[startup] Set peer URL to ${settings.peerUrl}`);
|
|
23904
|
+
await this.storage.set('settings', JSON.stringify(settings));
|
|
23905
|
+
}
|
|
23906
|
+
// Remove sensitive parameters from the URL
|
|
23907
|
+
if (hasHashSensitiveParam || hasSearchSensitiveParam) {
|
|
23908
|
+
sensitiveParams.forEach((p) => urlSearchParams.delete(p));
|
|
23909
|
+
const search = urlSearchParams.toString() ? `?${urlSearchParams}` : '';
|
|
23910
|
+
window.history.replaceState(null, '', window.location.pathname + search);
|
|
23911
|
+
}
|
|
23912
|
+
// Clear sessionStorage bridge after consumption (post-reload path only)
|
|
23913
|
+
if (data) {
|
|
23914
|
+
sessionStorage.removeItem(STARTUP_DATA_STORAGE_KEY);
|
|
23915
|
+
}
|
|
23916
|
+
// Remove the window bridge object
|
|
23917
|
+
delete window[STARTUP_DATA_STORAGE_KEY];
|
|
23918
|
+
}
|
|
23919
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: StartupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
23920
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: StartupService, providedIn: 'root' });
|
|
23921
|
+
}
|
|
23922
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: StartupService, decorators: [{
|
|
23923
|
+
type: Injectable,
|
|
23924
|
+
args: [{ providedIn: 'root' }]
|
|
23925
|
+
}] });
|
|
23926
|
+
function createAppStartupInitializer() {
|
|
23927
|
+
return () => inject(StartupService).start();
|
|
23928
|
+
}
|
|
23929
|
+
|
|
23787
23930
|
const TOKEN_STORAGE_KEY = 'token';
|
|
23788
23931
|
const PUBKEY_STORAGE_KEY = 'pubkey';
|
|
23789
23932
|
const SECKEY_STORAGE_KEY = 'seckey';
|
|
@@ -23980,6 +24123,7 @@ class AccountService extends BaseGraphqlService {
|
|
|
23980
24123
|
settings;
|
|
23981
24124
|
storage;
|
|
23982
24125
|
file;
|
|
24126
|
+
startupService;
|
|
23983
24127
|
translate;
|
|
23984
24128
|
toastController;
|
|
23985
24129
|
environment;
|
|
@@ -24055,13 +24199,14 @@ class AccountService extends BaseGraphqlService {
|
|
|
24055
24199
|
get remoteLocalSettingsKeys() {
|
|
24056
24200
|
return this._remoteLocalSettingsKeys;
|
|
24057
24201
|
}
|
|
24058
|
-
constructor(network, graphql, settings, storage, file, translate, toastController, environment, options, accountOptions) {
|
|
24202
|
+
constructor(network, graphql, settings, storage, file, startupService, translate, toastController, environment, options, accountOptions) {
|
|
24059
24203
|
super(graphql, environment);
|
|
24060
24204
|
this.network = network;
|
|
24061
24205
|
this.graphql = graphql;
|
|
24062
24206
|
this.settings = settings;
|
|
24063
24207
|
this.storage = storage;
|
|
24064
24208
|
this.file = file;
|
|
24209
|
+
this.startupService = startupService;
|
|
24065
24210
|
this.translate = translate;
|
|
24066
24211
|
this.toastController = toastController;
|
|
24067
24212
|
this.environment = environment;
|
|
@@ -24104,7 +24249,11 @@ class AccountService extends BaseGraphqlService {
|
|
|
24104
24249
|
this.restart();
|
|
24105
24250
|
}
|
|
24106
24251
|
}));
|
|
24107
|
-
|
|
24252
|
+
// Try to auto login, or restore locally
|
|
24253
|
+
const autoLogin = await this.autoLogin();
|
|
24254
|
+
if (!autoLogin) {
|
|
24255
|
+
await this.restoreLocally();
|
|
24256
|
+
}
|
|
24108
24257
|
await this.listenSettings();
|
|
24109
24258
|
return this._data;
|
|
24110
24259
|
}
|
|
@@ -24750,6 +24899,20 @@ class AccountService extends BaseGraphqlService {
|
|
|
24750
24899
|
.pipe(debounceTime(2000), filter(() => this.isLogin() && this.network.online))
|
|
24751
24900
|
.subscribe((settings) => this.saveLocalSettingsRemotely(settings)));
|
|
24752
24901
|
}
|
|
24902
|
+
async autoLogin() {
|
|
24903
|
+
if (!this.startupService?.hasAuth())
|
|
24904
|
+
return false; // Skip if no auth data
|
|
24905
|
+
try {
|
|
24906
|
+
const authData = this.startupService.consumeAuth();
|
|
24907
|
+
console.debug('[account] Attempting auto login as:', authData.username);
|
|
24908
|
+
await this.login(authData);
|
|
24909
|
+
return true;
|
|
24910
|
+
}
|
|
24911
|
+
catch (error) {
|
|
24912
|
+
console.warn('[account] Auto auth failed:', error);
|
|
24913
|
+
return false;
|
|
24914
|
+
}
|
|
24915
|
+
}
|
|
24753
24916
|
async restoreLocally() {
|
|
24754
24917
|
// Restore from storage
|
|
24755
24918
|
const values = await Promise.all([
|
|
@@ -25129,13 +25292,15 @@ class AccountService extends BaseGraphqlService {
|
|
|
25129
25292
|
showToast(opts) {
|
|
25130
25293
|
return Toasts.show(this.toastController, this.translate, opts);
|
|
25131
25294
|
}
|
|
25132
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AccountService, deps: [{ token: NetworkService }, { token: GraphqlService }, { token: LocalSettingsService }, { token: i2$4.Storage }, { token: FileService }, { token: i1$1.TranslateService, optional: true }, { token: i2$1.ToastController, optional: true }, { token: ENVIRONMENT }, { token: APP_USER_SETTINGS_OPTIONS, optional: true }, { token: APP_ACCOUNT_SERVICE_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
25295
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AccountService, deps: [{ token: NetworkService }, { token: GraphqlService }, { token: LocalSettingsService }, { token: i2$4.Storage }, { token: FileService }, { token: StartupService, optional: true }, { token: i1$1.TranslateService, optional: true }, { token: i2$1.ToastController, optional: true }, { token: ENVIRONMENT }, { token: APP_USER_SETTINGS_OPTIONS, optional: true }, { token: APP_ACCOUNT_SERVICE_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
25133
25296
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AccountService, providedIn: 'root' });
|
|
25134
25297
|
}
|
|
25135
25298
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AccountService, decorators: [{
|
|
25136
25299
|
type: Injectable,
|
|
25137
25300
|
args: [{ providedIn: 'root', deps: [ENVIRONMENT] }]
|
|
25138
|
-
}], ctorParameters: () => [{ type: NetworkService }, { type: GraphqlService }, { type: LocalSettingsService }, { type: i2$4.Storage }, { type: FileService }, { type:
|
|
25301
|
+
}], ctorParameters: () => [{ type: NetworkService }, { type: GraphqlService }, { type: LocalSettingsService }, { type: i2$4.Storage }, { type: FileService }, { type: StartupService, decorators: [{
|
|
25302
|
+
type: Optional
|
|
25303
|
+
}] }, { type: i1$1.TranslateService, decorators: [{
|
|
25139
25304
|
type: Optional
|
|
25140
25305
|
}] }, { type: i2$1.ToastController, decorators: [{
|
|
25141
25306
|
type: Optional
|