const Login = require('./login'); const Gui = require('./gui'); module.exports = new Class({ Extends: Vn.Object, Properties: { conn: { type: Db.Connection ,get() { return this._conn; } } } ,initialize() { window.addEventListener('error', e => this._onWindowError(e)); window.addEventListener('unhandledrejection', e => this._onWindowRejection(e)); window.addEventListener('unload', () => this._onWindowUnload()); this._hash = new Vn.Hash({window: window}); const conn = new Db.Connection(); this.link({_conn: conn}, {'error': this._onConnError}); this.initAutoLogin(); } ,run() { if (this.tryAutoLogin()) return; this.showLogin(); } ,showLogin() { const login = this._login = new Login({ conn: this._conn, hash: this._hash }); login.on('login', this._onLogin, this); login.show(); } ,async _onLogin() { this._freeLogin(); if (this._gui) return; const gui = this._gui = new Gui({ conn: this._conn, hash: this._hash }); gui.on('logout', this._onLogout, this); await gui.show(); } ,async _onLogout() { this.clearAutoLogin(); await this._freeGui(); this.loggingOut = false; this.showLogin(); } ,_onWindowUnload() { this.unref(); } ,async _logout() { if (this._gui && !this.loggingOut) { this.loggingOut = true; await this._gui.logout(); } } ,_newVersion() { if (this.ignoreVersion) return; this.ignoreVersion = true; const dialog = new Htk.Dialog({ message: _('New version available') ,buttons: Htk.Dialog.Button.ACCEPT ,icon: 'warning' }); dialog.on('response', this._onNewVersionResponse, this); dialog.open(); } ,_onNewVersionResponse() { location.reload(); } ,_freeLogin() { if (!this._login) return; this._login.disconnectByInstance(this); this._login.hide(); this._login.unref(); this._login = null; } ,async _freeGui() { if (!this._gui) return; this._gui.disconnectByInstance(this); await this._gui.hide(); this._gui.unref(); this._gui = null; } ,_destroy() { this._freeLogin(); this._freeGui(); this.deinitAutoLogin(); if (this._conn) this._conn.unref(); if (this._hash) this._hash.unref(); } // Auto login ,_firstLogin: true ,initAutoLogin() { const isGuest = new Vn.Param({ lot: this._hash, type: Boolean, name: 'guest' }); this.link({_isGuest: isGuest}, {'changed': this._onGuestChange}); const token = new Vn.Param({ lot: this._hash, type: String, name: 'token' }); this.link({_token: token}, {'changed': this._onTokenChange}); } ,_onGuestChange() { if (this._isGuest.value) setTimeout(this.tryAutoLogin.bind(this)); } ,_onTokenChange() { if (this._token.value) setTimeout(this.tryAutoLogin.bind(this)); } ,deinitAutoLogin() { if (this._isGuest) this._isGuest.unref(); if (this._token) this._token.unref(); } ,autoLogin() { const guest = localStorage.getItem('hederaGuest'); if (this._isGuest.value || guest) { localStorage.setItem('hederaGuest', true); return true; } if (this._token.value) this._conn.token = this._token.value; else this._conn.fetchToken(); if (this._conn.token) return true; return false; } ,tryAutoLogin() { const ok = this.autoLogin(); this._firstLogin = false; this._isGuest.value = undefined; this._token.value = undefined; if (!ok) return false; this._onLogin(); return true; } ,clearAutoLogin() { localStorage.removeItem('hederaGuest'); } // Error management ,_onWindowError(event) { this.globalHandler(event.error); } ,_onWindowRejection(event) { this.globalHandler(event.reason); } ,async _onConnError(conn, err) { if (!(err instanceof Vn.JsonException)) return; switch (err.exception) { case 'UserDisabled': Htk.Toast.showError(_('User disabled')); await this._logout(); return; case 'OutdatedVersion': this._newVersion(); return; } if (err.statusCode == 401 && !this._login) { Htk.Toast.showError(_('Session expired')); this._logout(); } } ,async globalHandler(err) { try { if (!err) return; if (err instanceof Vn.JsonException) { const statusCode = err.statusCode; if (statusCode >= 400 && statusCode < 500) { if (err.statusCode == 403) Htk.Toast.showError(_('You don\'t have enough privileges')); else { switch (err.exception) { case 'UserDisabled': case 'OutdatedVersion': return; } if (err.statusCode == 401) return; Htk.Toast.showError(err.message); } } else Htk.Toast.showError(err.message); } else { Htk.Toast.showError(_('Something went wrong')); if (this._conn) await this._conn.send('core/log', { file: err.fileName ,line: err.lineNumber ,message: err.message ,stack: err.stack ,agent: navigator.userAgent ,location: location.href }); } } catch(e) { console.error(e); } } });