2using System.Threading.Tasks;
4using System.Windows.Controls;
17 private string passwordHash =
string.Empty;
18 private string passwordHashMethod =
string.Empty;
23 this.ConnectionMethod_SelectionChanged(
this,
null);
31 get => this.passwordHash;
32 set => this.passwordHash = value;
40 get => this.passwordHashMethod;
41 set => this.passwordHashMethod = value;
44 private void CancelButton_Click(
object Sender, RoutedEventArgs e)
46 this.DialogResult =
false;
49 private async
void ConnectButton_Click(
object Sender, RoutedEventArgs e)
55 Host = this.XmppServer.Text,
56 Account = this.AccountName.Text
59 switch ((TransportMethod)this.ConnectionMethod.SelectedIndex)
61 case TransportMethod.TraditionalSocket:
62 if (!
int.TryParse(this.XmppPort.Text, out
int Port) || Port <= 0 || Port > 65535)
64 MessageBox.Show(
this,
"Invalid port number. Valid port numbers are positive integers between 1 and 65535. The default port number is " +
66 this.XmppPort.Focus();
70 Credentials.Port = Port;
73 case TransportMethod.WS:
77 Uri =
new Uri(this.UrlEndpoint.Text);
81 MessageBox.Show(
this,
"Invalid URI.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
82 this.UrlEndpoint.Focus();
86 string Scheme = Uri.Scheme.ToLower();
88 if (Scheme !=
"ws" && Scheme !=
"wss")
90 MessageBox.Show(
this,
"Resource must be an WS or WSS URI.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
91 this.UrlEndpoint.Focus();
95 if (!Uri.IsAbsoluteUri)
97 MessageBox.Show(
this,
"URI must be an absolute URI.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
98 this.UrlEndpoint.Focus();
102 Credentials.UriEndpoint = this.UrlEndpoint.Text;
105 case TransportMethod.BOSH:
108 Uri =
new Uri(this.UrlEndpoint.Text);
112 MessageBox.Show(
this,
"Invalid URI.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
113 this.UrlEndpoint.Focus();
117 Scheme = Uri.Scheme.ToLower();
119 if (Scheme !=
"http" && Scheme !=
"https")
121 MessageBox.Show(
this,
"Resource must be an HTTP or HTTPS URI.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
122 this.UrlEndpoint.Focus();
126 if (!Uri.IsAbsoluteUri)
128 MessageBox.Show(
this,
"URI must be an absolute URI.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
129 this.UrlEndpoint.Focus();
133 Credentials.UriEndpoint = this.UrlEndpoint.Text;
137 bool Create = this.CreateAccount.IsChecked.HasValue && this.CreateAccount.IsChecked.Value;
138 if (Create && this.Password.Password !=
this.RetypePassword.Password)
140 MessageBox.Show(
this,
"The two passwords must match.",
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
141 this.Password.Focus();
145 await this.CloseClient();
146 this.ConnectButton.IsEnabled =
false;
147 this.XmppServer.IsEnabled =
false;
148 this.ConnectionMethod.IsEnabled =
false;
149 this.XmppPort.IsEnabled =
false;
150 this.UrlEndpoint.IsEnabled =
false;
151 this.AccountName.IsEnabled =
false;
152 this.Password.IsEnabled =
false;
153 this.RetypePassword.IsEnabled =
false;
154 this.TrustServerCertificate.IsEnabled =
false;
155 this.CreateAccount.IsEnabled =
false;
157 if (this.Password.Password ==
this.passwordHash && !
string.IsNullOrEmpty(
this.passwordHash))
159 Credentials.Password = this.passwordHash;
160 Credentials.PasswordType = this.passwordHashMethod;
163 Credentials.Password = this.Password.Password;
165 if (this.AllowInsecureAuthentication.IsChecked.HasValue &&
this.AllowInsecureAuthentication.IsChecked.Value)
167 Credentials.AllowPlain =
true;
168 Credentials.AllowCramMD5 =
true;
169 Credentials.AllowDigestMD5 =
true;
172 if (this.TrustServerCertificate.IsChecked.HasValue &&
this.TrustServerCertificate.IsChecked.Value)
173 Credentials.TrustServer =
true;
175 this.client =
new XmppClient(Credentials,
"en", typeof(
App).Assembly)
177 AllowQuickLogin =
true
183 this.client.OnRegistrationForm += this.Client_OnRegistrationForm;
186 this.client.OnStateChanged += this.Client_OnStateChanged;
187 this.client.OnConnectionError += this.Client_OnConnectionError;
196 private async Task Client_OnRegistrationForm(
object _,
DataForm Form)
203 ParameterDialog Dialog = await ParameterDialog.CreateAsync(Form);
211 private Task Client_OnStateChanged(
object Sender,
XmppState NewState)
213 MainWindow.UpdateGui(this.XmppStateChanged, NewState);
214 return Task.CompletedTask;
217 private async Task XmppStateChanged(
object P)
224 this.ConnectionState.Content =
"Offline.";
228 this.ConnectionState.Content =
"Connecting.";
232 this.ConnectionState.Content =
"Stream negotiation.";
236 this.ConnectionState.Content =
"Stream opened.";
240 this.ConnectionState.Content =
"Starting encryption.";
244 this.ConnectionState.Content =
"Authenticating user.";
248 this.ConnectionState.Content =
"Registering account.";
252 this.ConnectionState.Content =
"Binding resource.";
256 this.ConnectionState.Content =
"Fetching roster.";
260 this.ConnectionState.Content =
"Setting presence.";
264 if (this.StorePassword.IsChecked.HasValue &&
this.StorePassword.IsChecked.Value)
266 this.passwordHash = this.Password.Password;
267 this.passwordHashMethod =
string.Empty;
275 this.ConnectionState.Content =
"Connected.";
276 await this.CloseClient();
277 this.DialogResult =
true;
281 this.ConnectionState.Content =
"Error.";
282 await this.CloseClient();
288 private async Task CloseClient()
290 if (!(this.client is
null))
297 this.ConnectButton.IsEnabled =
true;
298 this.XmppServer.IsEnabled =
true;
299 this.ConnectionMethod.IsEnabled =
true;
300 this.XmppPort.IsEnabled =
true;
301 this.UrlEndpoint.IsEnabled =
true;
302 this.AccountName.IsEnabled =
true;
303 this.Password.IsEnabled =
true;
304 this.TrustServerCertificate.IsEnabled =
true;
305 this.CreateAccount.IsEnabled =
true;
307 this.RetypePassword.IsEnabled = (this.CreateAccount.IsChecked.HasValue && this.CreateAccount.IsChecked.Value);
310 private Task Client_OnConnectionError(
object _, Exception Exception)
312 MainWindow.UpdateGui(this.ShowError, Exception);
313 return Task.CompletedTask;
316 private Task ShowError(
object P)
318 Exception ex = (Exception)P;
319 MessageBox.Show(
this, ex.Message,
"Error", MessageBoxButton.OK, MessageBoxImage.Error);
320 return Task.CompletedTask;
325 private void CreateAccount_Click(
object Sender, RoutedEventArgs e)
327 bool Create = this.CreateAccount.IsChecked.HasValue && this.CreateAccount.IsChecked.Value;
328 this.CreateParameters.Visibility = Create ? Visibility.Visible : Visibility.Collapsed;
329 this.RetypePassword.IsEnabled = Create;
332 private void ConnectionMethod_SelectionChanged(
object Sender, SelectionChangedEventArgs e)
334 if (this.PortLabel is
null)
337 switch ((TransportMethod)this.ConnectionMethod.SelectedIndex)
339 case TransportMethod.TraditionalSocket:
340 this.PortLabel.Visibility = Visibility.Visible;
341 this.XmppPort.Visibility = Visibility.Visible;
342 this.UrlEndpointLabel.Visibility = Visibility.Collapsed;
343 this.UrlEndpoint.Visibility = Visibility.Collapsed;
346 case TransportMethod.BOSH:
347 case TransportMethod.WS:
348 this.PortLabel.Visibility = Visibility.Collapsed;
349 this.XmppPort.Visibility = Visibility.Collapsed;
350 this.UrlEndpointLabel.Visibility = Visibility.Visible;
351 this.UrlEndpoint.Visibility = Visibility.Visible;
Interaction logic for App.xaml
Interaction logic for xaml
Manages an XMPP client connection. Implements XMPP, as defined in https://tools.ietf....
Task OfflineAndDisposeAsync()
Sends an offline presence, and then disposes the object by calling DisposeAsync.
string PasswordHashMethod
Password hash method.
string PasswordHash
Hash value of password. Depends on method used to authenticate user.
Task Connect()
Connects the client.
void AllowRegistration()
If registration of a new account is allowed. Requires a password. Having a password hash is not suffi...
Class containing credentials for an XMPP client connection.
const int DefaultPort
Default XMPP Server port.
XmppState
State of XMPP connection.