keeweb/app/scripts/app.js

203 lines
6.9 KiB
JavaScript
Raw Normal View History

2019-09-16 22:57:56 +02:00
import { Events } from 'framework/events';
2020-03-29 09:23:49 +02:00
import { StartProfiler } from 'comp/app/start-profiler';
2019-09-15 14:16:32 +02:00
import { FileInfoCollection } from 'collections/file-info-collection';
import { AppRightsChecker } from 'comp/app/app-rights-checker';
import { ExportApi } from 'comp/app/export-api';
import { SingleInstanceChecker } from 'comp/app/single-instance-checker';
import { Updater } from 'comp/app/updater';
2020-04-15 16:50:01 +02:00
import { UsbListener } from 'comp/app/usb-listener';
2019-09-15 14:16:32 +02:00
import { FeatureTester } from 'comp/browser/feature-tester';
import { FocusDetector } from 'comp/browser/focus-detector';
import { IdleTracker } from 'comp/browser/idle-tracker';
import { KeyHandler } from 'comp/browser/key-handler';
import { PopupNotifier } from 'comp/browser/popup-notifier';
import { Launcher } from 'comp/launcher';
import { SettingsManager } from 'comp/settings/settings-manager';
import { Alerts } from 'comp/ui/alerts';
import { Timeouts } from 'const/timeouts';
import { AppModel } from 'models/app-model';
import { AppSettingsModel } from 'models/app-settings-model';
import { RuntimeDataModel } from 'models/runtime-data-model';
import { UpdateModel } from 'models/update-model';
import { PluginManager } from 'plugins/plugin-manager';
import { Features } from 'util/features';
import { KdbxwebInit } from 'util/kdbxweb/kdbxweb-init';
import { Locale } from 'util/locale';
import { AppView } from 'views/app-view';
import 'hbs-helpers';
2020-05-05 16:34:39 +02:00
import { AutoType } from './auto-type';
import { Storage } from './storage';
2015-10-17 23:49:24 +02:00
2020-03-29 09:23:49 +02:00
StartProfiler.milestone('loading modules');
2019-08-16 23:05:39 +02:00
const ready = (Launcher && Launcher.ready) || $;
2017-02-05 11:08:26 +01:00
ready(() => {
2020-03-29 09:23:49 +02:00
StartProfiler.milestone('document ready');
2017-02-05 11:08:26 +01:00
const appModel = new AppModel();
2020-03-29 09:23:49 +02:00
StartProfiler.milestone('creating app model');
Promise.resolve()
.then(loadConfigs)
.then(initModules)
.then(loadRemoteConfig)
2017-05-16 22:56:52 +02:00
.then(ensureCanRun)
2020-05-05 16:34:39 +02:00
.then(initStorage)
2017-05-16 21:26:25 +02:00
.then(showApp)
.then(postInit)
2020-06-01 16:53:51 +02:00
.catch((e) => {
2017-05-16 21:26:25 +02:00
appModel.appLogger.error('Error starting app', e);
});
2017-02-05 11:08:26 +01:00
2017-05-16 22:56:52 +02:00
function ensureCanRun() {
if (Features.isFrame && !appModel.settings.allowIframes) {
return Promise.reject(
'Running in iframe is not allowed (this can be changed in the app config).'
);
}
2020-03-29 09:23:49 +02:00
return FeatureTester.test()
2020-06-01 16:53:51 +02:00
.catch((e) => {
2020-03-29 09:23:49 +02:00
Alerts.error({
header: Locale.appSettingsError,
2020-04-23 19:55:52 +02:00
body: Locale.appNotSupportedError,
pre: e,
2020-03-29 09:23:49 +02:00
buttons: [],
esc: false,
enter: false,
click: false
});
throw 'Feature testing failed: ' + e;
})
.then(() => {
StartProfiler.milestone('checking features');
2017-05-16 22:56:52 +02:00
});
}
function loadConfigs() {
return Promise.all([
2019-09-17 19:50:42 +02:00
AppSettingsModel.load(),
2019-09-17 21:56:58 +02:00
UpdateModel.load(),
2019-09-17 21:50:46 +02:00
RuntimeDataModel.load(),
2019-09-17 21:39:06 +02:00
FileInfoCollection.load()
2020-03-29 09:23:49 +02:00
]).then(() => {
StartProfiler.milestone('loading configs');
});
}
2016-06-16 19:00:24 +02:00
function initModules() {
KeyHandler.init();
PopupNotifier.init();
2017-01-30 21:26:31 +01:00
KdbxwebInit.init();
2019-01-21 20:52:40 +01:00
FocusDetector.init();
2020-05-05 16:34:39 +02:00
AutoType.init();
2016-06-16 19:00:24 +02:00
window.kw = ExportApi;
2020-03-29 09:23:49 +02:00
return PluginManager.init().then(() => {
StartProfiler.milestone('initializing modules');
});
2016-06-16 19:00:24 +02:00
}
function showSettingsLoadError() {
Alerts.error({
header: Locale.appSettingsError,
body: Locale.appSettingsErrorBody,
buttons: [],
2019-08-16 23:05:39 +02:00
esc: false,
enter: false,
click: false
2016-06-16 19:00:24 +02:00
});
}
function loadRemoteConfig() {
2020-03-29 09:23:49 +02:00
return Promise.resolve()
.then(() => {
SettingsManager.setBySettings(appModel.settings);
const configParam = getConfigParam();
if (configParam) {
return appModel
.loadConfig(configParam)
.then(() => {
SettingsManager.setBySettings(appModel.settings);
})
2020-06-01 16:53:51 +02:00
.catch((e) => {
2020-03-29 09:23:49 +02:00
if (!appModel.settings.cacheConfigSettings) {
showSettingsLoadError();
throw e;
}
});
}
})
.then(() => {
StartProfiler.milestone('loading remote config');
});
}
2020-05-05 16:34:39 +02:00
function initStorage() {
for (const prv of Object.values(Storage)) {
prv.init();
}
StartProfiler.milestone('initializing storage');
}
2015-10-17 23:49:24 +02:00
function showApp() {
2019-08-16 23:05:39 +02:00
return Promise.resolve().then(() => {
2019-08-18 08:05:38 +02:00
const skipHttpsWarning =
2019-09-17 19:50:42 +02:00
localStorage.skipHttpsWarning || appModel.settings.skipHttpsWarning;
2019-08-16 23:05:39 +02:00
const protocolIsInsecure = ['https:', 'file:', 'app:'].indexOf(location.protocol) < 0;
const hostIsInsecure = location.hostname !== 'localhost';
if (protocolIsInsecure && hostIsInsecure && !skipHttpsWarning) {
2020-06-01 16:53:51 +02:00
return new Promise((resolve) => {
2019-08-16 23:05:39 +02:00
Alerts.error({
header: Locale.appSecWarn,
icon: 'user-secret',
esc: false,
enter: false,
click: false,
2020-04-23 19:55:52 +02:00
body: Locale.appSecWarnBody1 + '\n\n' + Locale.appSecWarnBody2,
2019-08-16 23:05:39 +02:00
buttons: [{ result: '', title: Locale.appSecWarnBtn, error: true }],
complete: () => {
showView();
resolve();
}
2018-08-30 22:16:31 +02:00
});
2019-08-16 23:05:39 +02:00
});
} else {
showView();
2020-06-01 16:53:51 +02:00
return new Promise((resolve) => requestAnimationFrame(resolve));
2019-08-16 23:05:39 +02:00
}
});
2016-06-16 19:00:24 +02:00
}
function postInit() {
Updater.init();
SingleInstanceChecker.init();
AppRightsChecker.init();
2020-04-15 16:50:01 +02:00
IdleTracker.init();
UsbListener.init();
setTimeout(() => {
PluginManager.runAutoUpdate();
}, Timeouts.AutoUpdatePluginsAfterStart);
2017-05-20 12:46:21 +02:00
}
2016-06-16 19:00:24 +02:00
function showView() {
2019-09-16 17:43:57 +02:00
new AppView(appModel).render();
2020-03-29 09:23:49 +02:00
StartProfiler.milestone('first view rendering');
2019-09-16 22:57:56 +02:00
Events.emit('app-ready');
2020-03-29 09:23:49 +02:00
StartProfiler.milestone('app ready event');
2020-03-29 09:23:49 +02:00
StartProfiler.report();
2015-10-17 23:49:24 +02:00
}
2016-06-16 19:00:24 +02:00
function getConfigParam() {
2017-01-31 07:50:28 +01:00
const metaConfig = document.head.querySelector('meta[name=kw-config]');
if (metaConfig && metaConfig.content && metaConfig.content[0] !== '(') {
return metaConfig.content;
}
2017-01-31 07:50:28 +01:00
const match = location.search.match(/[?&]config=([^&]+)/i);
2016-06-16 19:00:24 +02:00
if (match && match[1]) {
return match[1];
}
}
2015-10-17 23:49:24 +02:00
});