Saving last nickname changed while beeing on the server

This commit is contained in:
WolverinDEV 2019-06-19 15:56:51 +02:00
parent e9bae1ee0c
commit 44ab896901
6 changed files with 113 additions and 72 deletions

View file

@ -68,6 +68,16 @@ interface VoiceStatus {
queries_visible: boolean; queries_visible: boolean;
} }
interface ConnectParameters {
nickname?: string;
channel?: {
target: string | number;
password?: string;
};
token?: string;
password?: {password: string, hashed: boolean};
}
class ConnectionHandler { class ConnectionHandler {
channelTree: ChannelTree; channelTree: ChannelTree;
@ -145,70 +155,65 @@ class ConnectionHandler {
setup() { } 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.tag_connection_handler.find(".server-name").text(tr("Connecting"));
this.cancel_reconnect(); this.cancel_reconnect();
this._reconnect_attempt = false; this._reconnect_attempt = false;
if(this.serverConnection) if(this.serverConnection)
this.handleDisconnect(DisconnectReason.REQUESTED); this.handleDisconnect(DisconnectReason.REQUESTED);
let idx = addr.lastIndexOf(':');
let port: number; let server_address: ServerAddress = {
let host: string; host: "",
if(idx != -1) { port: -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!<br>") + 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 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!<br>") + 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; const id = ++this._connect_initialize_id;
this.chat.serverChat().appendMessage(tr("Resolving hostname...")); 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) if(id != this._connect_initialize_id)
return; /* we're old */ return; /* we're old */
const _result = result || { target_ip: undefined, target_port: undefined }; server_address.port = resolved.target_port || server_address.port;
//if(!result) server_address.host = resolved.target_ip || server_address.host;
// throw "empty result"; this.chat.serverChat().appendMessage(tr("Hostname successfully resolved to {0}{1}"), true, server_address.host, server_address.port);
} catch(error) {
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 => {
if(id != this._connect_initialize_id) if(id != this._connect_initialize_id)
return; /* we're old */ return; /* we're old */
this.handleDisconnect(DisconnectReason.DNS_FAILED, error); 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(); this._certificate_modal.close();
popup.close(); /* no need, but nicer */ 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); const url = build_url(properties);
@ -457,10 +465,12 @@ class ConnectionHandler {
this.chat.serverChat().appendError(tr("Server requires password")); this.chat.serverChat().appendError(tr("Server requires password"));
createInputModal(tr("Server password"), tr("Enter server password:"), password => password.length != 0, password => { createInputModal(tr("Server password"), tr("Enter server password:"), password => password.length != 0, password => {
if(!(typeof password === "string")) return; 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.startConnection(this.serverConnection.remote_address().host + ":" + this.serverConnection.remote_address().port,
this.serverConnection.handshake_handler().profile, this.serverConnection.handshake_handler().profile,
this.serverConnection.handshake_handler().name, cprops);
{password: password as string, hashed: false});
}).open(); }).open();
break; break;
case DisconnectReason.CLIENT_KICKED: case DisconnectReason.CLIENT_KICKED:
@ -509,14 +519,13 @@ class ConnectionHandler {
console.log(tr("Allowed to auto reconnect. Reconnecting in 5000ms")); console.log(tr("Allowed to auto reconnect. Reconnecting in 5000ms"));
const server_address = this.serverConnection.remote_address(); const server_address = this.serverConnection.remote_address();
const profile = this.serverConnection.handshake_handler().profile; 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 = setTimeout(() => {
this._reconnect_timer = undefined; this._reconnect_timer = undefined;
this.chat.serverChat().appendMessage(tr("Reconnecting...")); this.chat.serverChat().appendMessage(tr("Reconnecting..."));
log.info(LogCategory.NETWORKING, tr("Reconnecting...")) log.info(LogCategory.NETWORKING, tr("Reconnecting..."));
this.startConnection(server_address.host + ":" + server_address.port, profile, name, password ? { password: password, hashed: true} : undefined);
this.startConnection(server_address.host + ":" + server_address.port, profile, this.reconnect_properties(profile));
this._reconnect_attempt = true; this._reconnect_attempt = true;
}, 5000); }, 5000);
} }
@ -665,4 +674,20 @@ class ConnectionHandler {
this.update_voice_status(undefined); 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
}
}
} }

View file

@ -13,13 +13,11 @@ namespace connection {
private failed = false; private failed = false;
readonly profile: profiles.ConnectionProfile; readonly profile: profiles.ConnectionProfile;
readonly name: string; readonly parameters: ConnectParameters;
readonly server_password: string;
constructor(profile: profiles.ConnectionProfile, name: string, password: string) { constructor(profile: profiles.ConnectionProfile, parameters: ConnectParameters) {
this.profile = profile; this.profile = profile;
this.server_password = password; this.parameters = parameters;
this.name = name;
} }
setConnection(con: AbstractServerConnection) { setConnection(con: AbstractServerConnection) {
@ -84,12 +82,16 @@ namespace connection {
const git_version = settings.static_global("version", "unknown"); const git_version = settings.static_global("version", "unknown");
const browser_name = (navigator.browserSpecs || {})["name"] || " "; const browser_name = (navigator.browserSpecs || {})["name"] || " ";
let data = { let data = {
client_nickname: this.name, client_nickname: this.parameters.nickname || "Another TeaSpeak user",
client_platform: (browser_name ? browser_name + " " : "") + navigator.platform, client_platform: (browser_name ? browser_name + " " : "") + navigator.platform,
client_version: "TeaWeb " + git_version + " (" + navigator.userAgent + ")", client_version: "TeaWeb " + git_version + " (" + navigator.userAgent + ")",
client_version_sign: undefined, 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_browser_engine: navigator.product,
client_input_hardware: this.connection.client.client_status.input_hardware, client_input_hardware: this.connection.client.client_status.input_hardware,

View file

@ -379,10 +379,13 @@ function main() {
if(profile && profile.valid()) { if(profile && profile.valid()) {
const connection = server_connections.active_connection_handler() || server_connections.spawn_server_connection_handler(); const connection = server_connections.active_connection_handler() || server_connections.spawn_server_connection_handler();
connection.startConnection(address, profile, username, password.length > 0 ? { connection.startConnection(address, profile, {
password: password, nickname: username,
hashed: password_hashed password: password.length > 0 ? {
} : undefined); password: password,
hashed: password_hashed
} : undefined
});
} else { } else {
Modals.spawnConnectModal({ Modals.spawnConnectModal({
url: address, url: address,

View file

@ -794,6 +794,8 @@ class ChannelEntry {
}); });
} }
cached_password() { return this._cachedPassword; }
async subscribe() : Promise<void> { async subscribe() : Promise<void> {
if(this.subscribe_mode == ChannelSubscribeMode.SUBSCRIBED) if(this.subscribe_mode == ChannelSubscribeMode.SUBSCRIBED)
return; return;

View file

@ -503,10 +503,12 @@ class ControlBar {
connection.startConnection( connection.startConnection(
mark.server_properties.server_address + ":" + mark.server_properties.server_port, mark.server_properties.server_address + ":" + mark.server_properties.server_port,
profile, profile,
mark.nickname,
{ {
password: mark.server_properties.server_password_hash, nickname: mark.nickname,
hashed: true password: {
password: mark.server_properties.server_password_hash,
hashed: true
}
} }
); );
} else { } else {

View file

@ -28,7 +28,7 @@ namespace Modals {
let updateFields = function () { let updateFields = function () {
console.log("Updating"); console.log("Updating");
if(selected_profile) 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 else
input_nickname.attr("placeholder", ""); input_nickname.attr("placeholder", "");
@ -48,7 +48,6 @@ namespace Modals {
button_connect_tab.prop("disabled", flag_disabled); 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.val(defaultHost.enforce ? defaultHost.url : settings.static_global(Settings.KEY_CONNECT_ADDRESS, defaultHost.url));
input_address input_address
.on("keyup", () => updateFields()) .on("keyup", () => updateFields())
@ -68,6 +67,7 @@ namespace Modals {
return true; return true;
}); });
const last_nickname = settings.static_global(Settings.KEY_CONNECT_USERNAME, undefined);
{ {
for(const profile of profiles.profiles()) { for(const profile of profiles.profiles()) {
input_profile.append( 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'); 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()); input_nickname.on("keyup", () => updateFields());
setTimeout(() => updateFields(), 100); setTimeout(() => updateFields(), 100);
@ -98,8 +101,10 @@ namespace Modals {
connection.startConnection( connection.startConnection(
input_address.val().toString(), input_address.val().toString(),
selected_profile, 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 { } else {
button_connect_tab.trigger('click'); button_connect_tab.trigger('click');
@ -113,8 +118,10 @@ namespace Modals {
connection.startConnection( connection.startConnection(
input_address.val().toString(), input_address.val().toString(),
selected_profile, 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}
}
); );
}); });
}, { }, {