From 44ab89690119dd034ff15a9b45deb7abad25c6d4 Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Wed, 19 Jun 2019 15:56:51 +0200 Subject: [PATCH] Saving last nickname changed while beeing on the server --- shared/js/ConnectionHandler.ts | 129 ++++++++++++++--------- shared/js/connection/HandshakeHandler.ts | 16 +-- shared/js/main.ts | 11 +- shared/js/ui/channel.ts | 2 + shared/js/ui/frames/ControlBar.ts | 8 +- shared/js/ui/modal/ModalConnect.ts | 19 ++-- 6 files changed, 113 insertions(+), 72 deletions(-) diff --git a/shared/js/ConnectionHandler.ts b/shared/js/ConnectionHandler.ts index 0e9a6a5a..c5ccd1f0 100644 --- a/shared/js/ConnectionHandler.ts +++ b/shared/js/ConnectionHandler.ts @@ -68,6 +68,16 @@ interface VoiceStatus { queries_visible: boolean; } +interface ConnectParameters { + nickname?: string; + channel?: { + target: string | number; + password?: string; + }; + token?: string; + password?: {password: string, hashed: boolean}; +} + class ConnectionHandler { channelTree: ChannelTree; @@ -145,70 +155,65 @@ class ConnectionHandler { setup() { } - startConnection(addr: string, profile: profiles.ConnectionProfile, name?: string, password?: {password: string, hashed: boolean}) { + async startConnection(addr: string, profile: profiles.ConnectionProfile, parameters: ConnectParameters) { this.tag_connection_handler.find(".server-name").text(tr("Connecting")); this.cancel_reconnect(); this._reconnect_attempt = false; if(this.serverConnection) this.handleDisconnect(DisconnectReason.REQUESTED); - let idx = addr.lastIndexOf(':'); - let port: number; - let host: string; - if(idx != -1) { - port = parseInt(addr.substr(idx + 1)); - host = addr.substr(0, idx); - } else { - host = addr; - port = 9987; - } - console.log(tr("Start connection to %s:%d"), host, port); - this.channelTree.initialiseHead(addr, {host, port}); - - this.chat.serverChat().appendMessage(tr("Initializing connection to {0}{1}"), true, host, port == 9987 ? "" : ":" + port); - const do_connect = (address: string, port: number) => { - const remote_address = { - host: address, - port: port - }; - - this.chat.serverChat().appendMessage(tr("Connecting to {0}{1}"), true, address, port == 9987 ? "" : ":" + port); - if(password && !password.hashed) { - helpers.hashPassword(password.password).then(password => { - /* errors will be already handled via the handle disconnect thing */ - this.serverConnection.connect(remote_address, new connection.HandshakeHandler(profile, name, password)); - }).catch(error => { - createErrorModal(tr("Error while hashing password"), tr("Failed to hash server password!
") + error).open(); - }) - } else { - /* errors will be already handled via the handle disconnect thing */ - this.serverConnection.connect(remote_address, new connection.HandshakeHandler(profile, name, password ? password.password : undefined)); - } + let server_address: ServerAddress = { + host: "", + port: -1 }; + { + let idx = addr.lastIndexOf(':'); + if(idx != -1) { + server_address.port = parseInt(addr.substr(idx + 1)); + server_address.host = addr.substr(0, idx); + } else { + server_address.host = addr; + server_address.port = 9987; + } + } + console.log(tr("Start connection to %s:%d"), server_address.host, server_address.port); + this.chat.serverChat().appendMessage(tr("Initializing connection to {0}{1}"), true, server_address.host, server_address.port == 9987 ? "" : ":" + server_address.port); + this.channelTree.initialiseHead(addr, server_address); - if(dns.supported() && !host.match(Modals.Regex.IP_V4) && !host.match(Modals.Regex.IP_V6)) { + if(parameters.password && !parameters.password.hashed){ + try { + const password = await helpers.hashPassword(parameters.password.password); + parameters.password = { + hashed: true, + password: password + } + } catch(error) { + console.error(tr("Failed to hash connect password: %o"), error); + createErrorModal(tr("Error while hashing password"), tr("Failed to hash server password!
") + error).open(); + } + } + + if(dns.supported() && !server_address.host.match(Modals.Regex.IP_V4) && !server_address.host.match(Modals.Regex.IP_V6)) { const id = ++this._connect_initialize_id; this.chat.serverChat().appendMessage(tr("Resolving hostname...")); - dns.resolve_address(host, { timeout: 5000 }).then(result => { + try { + const resolved = await dns.resolve_address(server_address.host, { timeout: 5000 }) || {} as any; if(id != this._connect_initialize_id) return; /* we're old */ - const _result = result || { target_ip: undefined, target_port: undefined }; - //if(!result) - // throw "empty result"; - - this.chat.serverChat().appendMessage(tr("Hostname successfully resolved to {0}"), true, _result.target_ip || host); - do_connect(_result.target_ip || host, _result.target_port || port); - }).catch(error => { + server_address.port = resolved.target_port || server_address.port; + server_address.host = resolved.target_ip || server_address.host; + this.chat.serverChat().appendMessage(tr("Hostname successfully resolved to {0}{1}"), true, server_address.host, server_address.port); + } catch(error) { if(id != this._connect_initialize_id) return; /* we're old */ this.handleDisconnect(DisconnectReason.DNS_FAILED, error); - }); - } else { - do_connect(host, port); + } } + + await this.serverConnection.connect(server_address, new connection.HandshakeHandler(profile, parameters)); } @@ -329,7 +334,10 @@ class ConnectionHandler { this._certificate_modal.close(); popup.close(); /* no need, but nicer */ - this.startConnection(properties.connect_address, profiles.find_profile(properties.connect_profile) || profiles.default_profile()); + + const profile = profiles.find_profile(properties.connect_profile) || profiles.default_profile(); + const cprops = this.reconnect_properties(profile); + this.startConnection(properties.connect_address, profile, cprops); }); const url = build_url(properties); @@ -457,10 +465,12 @@ class ConnectionHandler { this.chat.serverChat().appendError(tr("Server requires password")); createInputModal(tr("Server password"), tr("Enter server password:"), password => password.length != 0, password => { if(!(typeof password === "string")) return; + + const cprops = this.reconnect_properties(this.serverConnection.handshake_handler().profile); + cprops.password = {password: password as string, hashed: false}; this.startConnection(this.serverConnection.remote_address().host + ":" + this.serverConnection.remote_address().port, this.serverConnection.handshake_handler().profile, - this.serverConnection.handshake_handler().name, - {password: password as string, hashed: false}); + cprops); }).open(); break; case DisconnectReason.CLIENT_KICKED: @@ -509,14 +519,13 @@ class ConnectionHandler { console.log(tr("Allowed to auto reconnect. Reconnecting in 5000ms")); const server_address = this.serverConnection.remote_address(); const profile = this.serverConnection.handshake_handler().profile; - const name = this.getClient().clientNickName(); - const password = this.serverConnection.handshake_handler().server_password; this._reconnect_timer = setTimeout(() => { this._reconnect_timer = undefined; this.chat.serverChat().appendMessage(tr("Reconnecting...")); - log.info(LogCategory.NETWORKING, tr("Reconnecting...")) - this.startConnection(server_address.host + ":" + server_address.port, profile, name, password ? { password: password, hashed: true} : undefined); + log.info(LogCategory.NETWORKING, tr("Reconnecting...")); + + this.startConnection(server_address.host + ":" + server_address.port, profile, this.reconnect_properties(profile)); this._reconnect_attempt = true; }, 5000); } @@ -665,4 +674,20 @@ class ConnectionHandler { this.update_voice_status(undefined); }); } + + reconnect_properties(profile?: profiles.ConnectionProfile) : ConnectParameters { + const name = (this.getClient() ? this.getClient().clientNickName() : "") || + (this.serverConnection && this.serverConnection.handshake_handler() ? this.serverConnection.handshake_handler().parameters.nickname : "") || + settings.static_global(Settings.KEY_CONNECT_USERNAME, profile ? profile.default_username : undefined) || + "Another TeaSpeak user"; + const channel = (this.getClient() && this.getClient().currentChannel() ? this.getClient().currentChannel().channelId : 0) || + (this.serverConnection && this.serverConnection.handshake_handler() ? (this.serverConnection.handshake_handler().parameters.channel || {} as any).target : ""); + const channel_password = (this.getClient() && this.getClient().currentChannel() ? this.getClient().currentChannel().cached_password() : "") || + (this.serverConnection && this.serverConnection.handshake_handler() ? (this.serverConnection.handshake_handler().parameters.channel || {} as any).password : ""); + return { + channel: channel ? {target: "/" + channel, password: channel_password} : undefined, + nickname: name, + password: this.serverConnection && this.serverConnection.handshake_handler() ? this.serverConnection.handshake_handler().parameters.password : undefined + } + } } \ No newline at end of file diff --git a/shared/js/connection/HandshakeHandler.ts b/shared/js/connection/HandshakeHandler.ts index 83d70002..5d983564 100644 --- a/shared/js/connection/HandshakeHandler.ts +++ b/shared/js/connection/HandshakeHandler.ts @@ -13,13 +13,11 @@ namespace connection { private failed = false; readonly profile: profiles.ConnectionProfile; - readonly name: string; - readonly server_password: string; + readonly parameters: ConnectParameters; - constructor(profile: profiles.ConnectionProfile, name: string, password: string) { + constructor(profile: profiles.ConnectionProfile, parameters: ConnectParameters) { this.profile = profile; - this.server_password = password; - this.name = name; + this.parameters = parameters; } setConnection(con: AbstractServerConnection) { @@ -84,12 +82,16 @@ namespace connection { const git_version = settings.static_global("version", "unknown"); const browser_name = (navigator.browserSpecs || {})["name"] || " "; let data = { - client_nickname: this.name, + client_nickname: this.parameters.nickname || "Another TeaSpeak user", client_platform: (browser_name ? browser_name + " " : "") + navigator.platform, client_version: "TeaWeb " + git_version + " (" + navigator.userAgent + ")", client_version_sign: undefined, - client_server_password: this.server_password, + client_default_channel: (this.parameters.channel || {} as any).target, + client_default_channel_password: (this.parameters.channel || {} as any).password, + client_default_token: this.parameters.token, + + client_server_password: this.parameters.password ? this.parameters.password.password : undefined, client_browser_engine: navigator.product, client_input_hardware: this.connection.client.client_status.input_hardware, diff --git a/shared/js/main.ts b/shared/js/main.ts index 432363cb..e37c4dbe 100644 --- a/shared/js/main.ts +++ b/shared/js/main.ts @@ -379,10 +379,13 @@ function main() { if(profile && profile.valid()) { const connection = server_connections.active_connection_handler() || server_connections.spawn_server_connection_handler(); - connection.startConnection(address, profile, username, password.length > 0 ? { - password: password, - hashed: password_hashed - } : undefined); + connection.startConnection(address, profile, { + nickname: username, + password: password.length > 0 ? { + password: password, + hashed: password_hashed + } : undefined + }); } else { Modals.spawnConnectModal({ url: address, diff --git a/shared/js/ui/channel.ts b/shared/js/ui/channel.ts index 3201848b..158a8d54 100644 --- a/shared/js/ui/channel.ts +++ b/shared/js/ui/channel.ts @@ -794,6 +794,8 @@ class ChannelEntry { }); } + cached_password() { return this._cachedPassword; } + async subscribe() : Promise { if(this.subscribe_mode == ChannelSubscribeMode.SUBSCRIBED) return; diff --git a/shared/js/ui/frames/ControlBar.ts b/shared/js/ui/frames/ControlBar.ts index 07c37336..d00c3aaa 100644 --- a/shared/js/ui/frames/ControlBar.ts +++ b/shared/js/ui/frames/ControlBar.ts @@ -503,10 +503,12 @@ class ControlBar { connection.startConnection( mark.server_properties.server_address + ":" + mark.server_properties.server_port, profile, - mark.nickname, { - password: mark.server_properties.server_password_hash, - hashed: true + nickname: mark.nickname, + password: { + password: mark.server_properties.server_password_hash, + hashed: true + } } ); } else { diff --git a/shared/js/ui/modal/ModalConnect.ts b/shared/js/ui/modal/ModalConnect.ts index 910f8159..11b118b1 100644 --- a/shared/js/ui/modal/ModalConnect.ts +++ b/shared/js/ui/modal/ModalConnect.ts @@ -28,7 +28,7 @@ namespace Modals { let updateFields = function () { console.log("Updating"); if(selected_profile) - input_nickname.attr("placeholder", settings.static_global(Settings.KEY_CONNECT_USERNAME, selected_profile.default_username)); + input_nickname.attr("placeholder", selected_profile.default_username); else input_nickname.attr("placeholder", ""); @@ -48,7 +48,6 @@ namespace Modals { button_connect_tab.prop("disabled", flag_disabled); }; - input_nickname.val(settings.static_global(Settings.KEY_CONNECT_USERNAME, undefined)); input_address.val(defaultHost.enforce ? defaultHost.url : settings.static_global(Settings.KEY_CONNECT_ADDRESS, defaultHost.url)); input_address .on("keyup", () => updateFields()) @@ -68,6 +67,7 @@ namespace Modals { return true; }); + const last_nickname = settings.static_global(Settings.KEY_CONNECT_USERNAME, undefined); { for(const profile of profiles.profiles()) { input_profile.append( @@ -86,7 +86,10 @@ namespace Modals { }); input_profile.val(connect_profile && connect_profile.enforce ? connect_profile.profile.id : connect_profile && connect_profile.profile ? connect_profile.profile.id : 'default').trigger('change'); } + if(last_nickname) /* restore */ + settings.changeGlobal(Settings.KEY_CONNECT_USERNAME, last_nickname); + input_nickname.val(last_nickname); input_nickname.on("keyup", () => updateFields()); setTimeout(() => updateFields(), 100); @@ -98,8 +101,10 @@ namespace Modals { connection.startConnection( input_address.val().toString(), selected_profile, - input_nickname.val().toString() || selected_profile.default_username, - {password: input_password.val().toString(), hashed: false} + { + nickname: input_nickname.val().toString() || selected_profile.default_username, + password: {password: input_password.val().toString(), hashed: false} + } ); } else { button_connect_tab.trigger('click'); @@ -113,8 +118,10 @@ namespace Modals { connection.startConnection( input_address.val().toString(), selected_profile, - input_nickname.val().toString() || selected_profile.default_username, - {password: input_password.val().toString(), hashed: false} + { + nickname: input_nickname.val().toString() || selected_profile.default_username, + password: {password: input_password.val().toString(), hashed: false} + } ); }); }, {