diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form
index e64e95e503..d9d21a7e60 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.form
@@ -59,11 +59,13 @@
-
+
+
+
@@ -115,10 +117,11 @@
+
-
-
+
+
@@ -242,5 +245,13 @@
+
+
+
+
+
+
+
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
index 557e251042..d2a9c5e04b 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/ConnectDialog.java
@@ -77,6 +77,7 @@ public class ConnectDialog extends MageDialog {
private Connection connection;
private ConnectTask task;
private RegisterUserDialog registerUserDialog;
+ private ResetPasswordDialog resetPasswordDialog;
private final ActionListener connectAction = new ActionListener() {
@Override
@@ -98,6 +99,9 @@ public class ConnectDialog extends MageDialog {
registerUserDialog = new RegisterUserDialog();
MageFrame.getDesktop().add(registerUserDialog, JLayeredPane.POPUP_LAYER);
+
+ resetPasswordDialog = new ResetPasswordDialog();
+ MageFrame.getDesktop().add(resetPasswordDialog, JLayeredPane.POPUP_LAYER);
}
public void showDialog() {
@@ -157,6 +161,7 @@ public class ConnectDialog extends MageDialog {
btnCancel = new javax.swing.JButton();
lblStatus = new javax.swing.JLabel();
btnRegister = new javax.swing.JButton();
+ btnForgotPassword = new javax.swing.JButton();
setTitle("Connect to server");
setNormalBounds(new java.awt.Rectangle(100, 100, 410, 307));
@@ -237,6 +242,13 @@ public class ConnectDialog extends MageDialog {
}
});
+ btnForgotPassword.setText("Forgot password");
+ btnForgotPassword.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnForgotPasswordActionPerformed(evt);
+ }
+ });
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
@@ -269,11 +281,13 @@ public class ConnectDialog extends MageDialog {
.addComponent(chkAutoConnect, javax.swing.GroupLayout.DEFAULT_SIZE, 375, Short.MAX_VALUE)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(btnRegister)
.addGroup(layout.createSequentialGroup()
.addComponent(btnConnect)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnForgotPassword)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnCancel)))
.addGap(26, 26, 26)))
.addContainerGap())
@@ -313,10 +327,11 @@ public class ConnectDialog extends MageDialog {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnConnect)
- .addComponent(btnCancel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCancel)
+ .addComponent(btnForgotPassword))
+ .addGap(3, 3, 3)
.addComponent(btnRegister)
- .addGap(3, 3, 3))
+ .addContainerGap())
);
pack();
@@ -566,10 +581,15 @@ public class ConnectDialog extends MageDialog {
registerUserDialog.showDialog();
}//GEN-LAST:event_btnRegisterActionPerformed
+ private void btnForgotPasswordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnForgotPasswordActionPerformed
+ resetPasswordDialog.showDialog();
+ }//GEN-LAST:event_btnForgotPasswordActionPerformed
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnCancel;
private javax.swing.JButton btnConnect;
private javax.swing.JButton btnFind;
+ private javax.swing.JButton btnForgotPassword;
private javax.swing.JButton btnRegister;
private mage.client.util.gui.countryBox.CountryComboBox cbFlag;
private javax.swing.JCheckBox chkAutoConnect;
diff --git a/Mage.Client/src/main/java/mage/client/dialog/RegisterUserDialog.java b/Mage.Client/src/main/java/mage/client/dialog/RegisterUserDialog.java
index e6e989da65..c7c132a14c 100644
--- a/Mage.Client/src/main/java/mage/client/dialog/RegisterUserDialog.java
+++ b/Mage.Client/src/main/java/mage/client/dialog/RegisterUserDialog.java
@@ -234,16 +234,15 @@ public class RegisterUserDialog extends MageDialog {
try {
get(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (result) {
- lblStatus.setText("Registration succeeded");
- MageFrame.getInstance().showMessage("Registration succeeded");
+ String message = "Registration succeeded";
+ lblStatus.setText(message);
+ MageFrame.getInstance().showMessage(message);
hideDialog();
} else {
lblStatus.setText("Could not register");
}
- } catch (InterruptedException ex) {
- logger.fatal("Update Players Task error", ex);
- } catch (ExecutionException ex) {
- logger.fatal("Update Players Task error", ex);
+ } catch (InterruptedException | ExecutionException ex) {
+ logger.fatal("Registration task error", ex);
} catch (CancellationException ex) {
logger.info("Registration was canceled");
lblStatus.setText("Registration was canceled (but an account might have been actually created)");
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ResetPasswordDialog.form b/Mage.Client/src/main/java/mage/client/dialog/ResetPasswordDialog.form
new file mode 100644
index 0000000000..448116ad45
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/dialog/ResetPasswordDialog.form
@@ -0,0 +1,279 @@
+
+
+
diff --git a/Mage.Client/src/main/java/mage/client/dialog/ResetPasswordDialog.java b/Mage.Client/src/main/java/mage/client/dialog/ResetPasswordDialog.java
new file mode 100644
index 0000000000..2d338884e3
--- /dev/null
+++ b/Mage.Client/src/main/java/mage/client/dialog/ResetPasswordDialog.java
@@ -0,0 +1,393 @@
+package mage.client.dialog;
+
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.swing.SwingWorker;
+import mage.client.MageFrame;
+import mage.client.util.Config;
+import mage.remote.Connection;
+import mage.remote.Session;
+import mage.remote.SessionImpl;
+import org.apache.log4j.Logger;
+
+public class ResetPasswordDialog extends MageDialog {
+
+ private static final Logger logger = Logger.getLogger(ResetPasswordDialog.class);
+ private Connection connection;
+ private Session session;
+ private GetAuthTokenTask getAuthTokenTask;
+ private ResetPasswordTask resetPasswordTask;
+
+ /**
+ * Creates new form ResetPasswordDialog
+ */
+ public ResetPasswordDialog() {
+ initComponents();
+ }
+
+ public void showDialog() {
+ this.setModal(true);
+ this.setLocation(50, 50);
+ this.setVisible(true);
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel2 = new javax.swing.JPanel();
+ jLabel6 = new javax.swing.JLabel();
+ lblAuthToken = new javax.swing.JLabel();
+ lblPassword = new javax.swing.JLabel();
+ lblPasswordConfirmation = new javax.swing.JLabel();
+ txtAuthToken = new javax.swing.JTextField();
+ btnSubmitNewPassword = new javax.swing.JButton();
+ lblPasswordConfirmationReasoning = new javax.swing.JLabel();
+ txtPassword = new javax.swing.JPasswordField();
+ txtPasswordConfirmation = new javax.swing.JPasswordField();
+ jPanel1 = new javax.swing.JPanel();
+ jLabel5 = new javax.swing.JLabel();
+ lblEmail = new javax.swing.JLabel();
+ txtEmail = new javax.swing.JTextField();
+ btnGetAuthToken = new javax.swing.JButton();
+ lblStatus = new javax.swing.JLabel();
+ btnCancel = new javax.swing.JButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("Reset password");
+
+ jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ jLabel6.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
+ jLabel6.setText("Step 2:");
+
+ lblAuthToken.setLabelFor(txtAuthToken);
+ lblAuthToken.setText("Auth token:");
+
+ lblPassword.setLabelFor(txtPassword);
+ lblPassword.setText("New password:");
+
+ lblPasswordConfirmation.setLabelFor(txtPasswordConfirmation);
+ lblPasswordConfirmation.setText("New password:");
+
+ btnSubmitNewPassword.setText("Submit a new password");
+ btnSubmitNewPassword.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSubmitNewPasswordActionPerformed(evt);
+ }
+ });
+
+ lblPasswordConfirmationReasoning.setFont(new java.awt.Font("Lucida Grande", 0, 10)); // NOI18N
+ lblPasswordConfirmationReasoning.setLabelFor(txtPasswordConfirmation);
+ lblPasswordConfirmationReasoning.setText("(confirmation)");
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addComponent(jLabel6)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(lblAuthToken, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblPassword, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblPasswordConfirmation, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtAuthToken)
+ .addComponent(txtPassword)
+ .addComponent(txtPasswordConfirmation)))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
+ .addGap(0, 204, Short.MAX_VALUE)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblPasswordConfirmationReasoning, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(btnSubmitNewPassword, javax.swing.GroupLayout.Alignment.TRAILING))))
+ .addContainerGap())
+ );
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel2Layout.createSequentialGroup()
+ .addComponent(jLabel6)
+ .addGap(24, 24, 24)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblAuthToken)
+ .addComponent(txtAuthToken, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblPassword)
+ .addComponent(txtPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblPasswordConfirmation)
+ .addComponent(txtPasswordConfirmation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblPasswordConfirmationReasoning)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(btnSubmitNewPassword)
+ .addContainerGap(9, Short.MAX_VALUE))
+ );
+
+ jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ jLabel5.setFont(new java.awt.Font("Lucida Grande", 1, 13)); // NOI18N
+ jLabel5.setText("Step 1:");
+
+ lblEmail.setLabelFor(txtEmail);
+ lblEmail.setText("Email:");
+
+ btnGetAuthToken.setText("Email an auth token");
+ btnGetAuthToken.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnGetAuthTokenActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jLabel5)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(lblEmail)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(txtEmail))
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addGap(0, 0, Short.MAX_VALUE)
+ .addComponent(btnGetAuthToken)))
+ .addContainerGap())
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addComponent(jLabel5)
+ .addGap(24, 24, 24)
+ .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblEmail)
+ .addComponent(txtEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(btnGetAuthToken)
+ .addContainerGap())
+ );
+
+ btnCancel.setText("Cancel");
+ btnCancel.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnCancelActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGap(0, 0, Short.MAX_VALUE)
+ .addComponent(btnCancel))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(lblStatus, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(7, 7, 7)
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCancel)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void btnGetAuthTokenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGetAuthTokenActionPerformed
+ if (this.txtEmail.getText().length() == 0) {
+ MageFrame.getInstance().showError("Please enter an email address.");
+ return;
+ }
+
+ connection = new Connection();
+
+ // Use the default setting for server connection.
+ connection.setHost(MageFrame.getPreferences().get("serverAddress", Config.serverName));
+ connection.setPort(Integer.valueOf(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port))));
+ PreferencesDialog.setProxyInformation(connection);
+
+ connection.setEmail(this.txtEmail.getText().trim());
+
+ getAuthTokenTask = new GetAuthTokenTask();
+ getAuthTokenTask.execute();
+ }//GEN-LAST:event_btnGetAuthTokenActionPerformed
+
+ private void btnSubmitNewPasswordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSubmitNewPasswordActionPerformed
+ if (this.txtEmail.getText().length() == 0) {
+ MageFrame.getInstance().showError("Please enter an email address.");
+ return;
+ }
+ if (this.txtAuthToken.getText().length() == 0) {
+ MageFrame.getInstance().showError("Please enter an auth token.");
+ return;
+ }
+ if (this.txtPassword.getText().length() == 0) {
+ MageFrame.getInstance().showError("Please enter a new password.");
+ return;
+ }
+ if (!this.txtPassword.getText().equals(this.txtPasswordConfirmation.getText())) {
+ MageFrame.getInstance().showError("Passwords don't match.");
+ return;
+ }
+
+ connection = new Connection();
+
+ // Use the default setting for server connection.
+ connection.setHost(MageFrame.getPreferences().get("serverAddress", Config.serverName));
+ connection.setPort(Integer.valueOf(MageFrame.getPreferences().get("serverPort", Integer.toString(Config.port))));
+ PreferencesDialog.setProxyInformation(connection);
+
+ connection.setEmail(this.txtEmail.getText().trim());
+ connection.setAuthToken(this.txtAuthToken.getText().trim());
+ connection.setPassword(this.txtPassword.getText().trim());
+
+ resetPasswordTask = new ResetPasswordTask();
+ resetPasswordTask.execute();
+ }//GEN-LAST:event_btnSubmitNewPasswordActionPerformed
+
+ private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
+ this.hideDialog();
+ }//GEN-LAST:event_btnCancelActionPerformed
+
+ void disableButtons() {
+ btnGetAuthToken.setEnabled(false);
+ btnSubmitNewPassword.setEnabled(false);
+ }
+
+ void enableButtons() {
+ btnGetAuthToken.setEnabled(true);
+ btnSubmitNewPassword.setEnabled(true);
+ }
+
+ private class GetAuthTokenTask extends SwingWorker {
+
+ private boolean result = false;
+
+ private static final int CONNECTION_TIMEOUT_MS = 2100;
+
+ @Override
+ protected Boolean doInBackground() throws Exception {
+ lblStatus.setText("Connecting...");
+ disableButtons();
+ session = new SessionImpl(MageFrame.getInstance());
+ result = session.emailAuthToken(connection);
+ return result;
+ }
+
+ @Override
+ protected void done() {
+ try {
+ get(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (result) {
+ String message = "Auth token is emailed. Please check your inbox.";
+ lblStatus.setText(message);
+ MageFrame.getInstance().showMessage(message);
+ } else {
+ lblStatus.setText("There was an issue while requesting an auth token.");
+ }
+ } catch (InterruptedException | ExecutionException ex) {
+ logger.fatal("Get Auth Token Task error", ex);
+ } catch (CancellationException ex) {
+ logger.info("Canceled");
+ lblStatus.setText("Canceled");
+ } catch (TimeoutException ex) {
+ logger.fatal("Timeout: ", ex);
+ } finally {
+ MageFrame.stopConnecting();
+ enableButtons();
+ }
+ }
+ }
+
+ private class ResetPasswordTask extends SwingWorker {
+
+ private boolean result = false;
+
+ private static final int CONNECTION_TIMEOUT_MS = 2100;
+
+ @Override
+ protected Boolean doInBackground() throws Exception {
+ lblStatus.setText("Connecting...");
+ disableButtons();
+ session = new SessionImpl(MageFrame.getInstance());
+ result = session.resetPassword(connection);
+ return result;
+ }
+
+ @Override
+ protected void done() {
+ try {
+ get(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ if (result) {
+ String message = "Password is reset successfully.";
+ lblStatus.setText(message);
+ MageFrame.getInstance().showMessage(message);
+ hideDialog();
+ } else {
+ lblStatus.setText("There was an issue while resetting password.");
+ }
+ } catch (InterruptedException | ExecutionException ex) {
+ logger.fatal("Reset Password Task error", ex);
+ } catch (CancellationException ex) {
+ logger.info("Canceled");
+ lblStatus.setText("Canceled");
+ } catch (TimeoutException ex) {
+ logger.fatal("Timeout: ", ex);
+ } finally {
+ MageFrame.stopConnecting();
+ enableButtons();
+ }
+ }
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnCancel;
+ private javax.swing.JButton btnGetAuthToken;
+ private javax.swing.JButton btnSubmitNewPassword;
+ private javax.swing.JLabel jLabel5;
+ private javax.swing.JLabel jLabel6;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JLabel lblAuthToken;
+ private javax.swing.JLabel lblEmail;
+ private javax.swing.JLabel lblPassword;
+ private javax.swing.JLabel lblPasswordConfirmation;
+ private javax.swing.JLabel lblPasswordConfirmationReasoning;
+ private javax.swing.JLabel lblStatus;
+ private javax.swing.JTextField txtAuthToken;
+ private javax.swing.JTextField txtEmail;
+ private javax.swing.JPasswordField txtPassword;
+ private javax.swing.JPasswordField txtPasswordConfirmation;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/Mage.Common/src/mage/interfaces/MageServer.java b/Mage.Common/src/mage/interfaces/MageServer.java
index ac4dbf84ab..83ffce61e4 100644
--- a/Mage.Common/src/mage/interfaces/MageServer.java
+++ b/Mage.Common/src/mage/interfaces/MageServer.java
@@ -58,6 +58,10 @@ public interface MageServer {
// registers a user to the user DB.
boolean registerUser(String sessionId, String userName, String password, String email) throws MageException;
+ boolean emailAuthToken(String sessionId, String email) throws MageException;
+
+ boolean resetPassword(String sessionId, String email, String authToken, String password) throws MageException;
+
// connection methods
// DEPRECATED - Use connectUser instead. This is only kept for older clients.
// This can be deleted once users transitioned to newer clients (1.4.6v1 and later).
diff --git a/Mage.Common/src/mage/remote/Connection.java b/Mage.Common/src/mage/remote/Connection.java
index 818ef0b46f..2a989da8dc 100644
--- a/Mage.Common/src/mage/remote/Connection.java
+++ b/Mage.Common/src/mage/remote/Connection.java
@@ -46,6 +46,7 @@ public class Connection {
private String username;
private String password;
private String email;
+ private String authToken;
private String adminPassword;
private ProxyType proxyType;
private String proxyHost;
@@ -182,6 +183,14 @@ public class Connection {
this.email = email;
}
+ public String getAuthToken() {
+ return authToken;
+ }
+
+ public void setAuthToken(String authToken) {
+ this.authToken = authToken;
+ }
+
public String getAdminPassword() {
return adminPassword;
}
diff --git a/Mage.Common/src/mage/remote/SessionImpl.java b/Mage.Common/src/mage/remote/SessionImpl.java
index 5a5d393218..4960fdfd74 100644
--- a/Mage.Common/src/mage/remote/SessionImpl.java
+++ b/Mage.Common/src/mage/remote/SessionImpl.java
@@ -204,6 +204,36 @@ public class SessionImpl implements Session {
});
}
+ @Override
+ public synchronized boolean emailAuthToken(final Connection connection) {
+ return establishJBossRemotingConnection(connection) && handleRemotingTaskExceptions(new RemotingTask() {
+ @Override
+ public boolean run() throws Throwable {
+ logger.info("Trying to ask for an auth token to " + getEmail() + " to XMAGE server at " + connection.getHost() + ":" + connection.getPort());
+ boolean result = server.emailAuthToken(sessionId, connection.getEmail());
+ if (result) {
+ logger.info("An auth token is emailed to " + getEmail() + " from MAGE server at " + connection.getHost() + ":" + connection.getPort());
+ }
+ return result;
+ }
+ });
+ }
+
+ @Override
+ public synchronized boolean resetPassword(final Connection connection) {
+ return establishJBossRemotingConnection(connection) && handleRemotingTaskExceptions(new RemotingTask() {
+ @Override
+ public boolean run() throws Throwable {
+ logger.info("Trying reset the password in XMAGE server at " + connection.getHost() + ":" + connection.getPort());
+ boolean result = server.resetPassword(sessionId, connection.getEmail(), connection.getAuthToken(), connection.getPassword());
+ if (result) {
+ logger.info("Password is successfully reset in MAGE server at " + connection.getHost() + ":" + connection.getPort());
+ }
+ return result;
+ }
+ });
+ }
+
@Override
public synchronized boolean connect(final Connection connection) {
return establishJBossRemotingConnection(connection) && handleRemotingTaskExceptions(new RemotingTask() {
@@ -1445,6 +1475,16 @@ public class SessionImpl implements Session {
return username == null ? "" : username;
}
+ private String getEmail() {
+ String email = connection.getEmail();
+ return email == null ? "" : email;
+ }
+
+ private String getAuthToken() {
+ String authToken = connection.getAuthToken();
+ return authToken == null ? "" : authToken;
+ }
+
@Override
public boolean updatePreferencesForServer(UserData userData) {
try {
diff --git a/Mage.Common/src/mage/remote/interfaces/Connect.java b/Mage.Common/src/mage/remote/interfaces/Connect.java
index 2b5921e2e7..3eeff3eebe 100644
--- a/Mage.Common/src/mage/remote/interfaces/Connect.java
+++ b/Mage.Common/src/mage/remote/interfaces/Connect.java
@@ -36,6 +36,10 @@ public interface Connect {
boolean register(Connection connection);
+ boolean emailAuthToken(Connection connection);
+
+ boolean resetPassword(Connection connection);
+
boolean connect(Connection connection);
boolean stopConnecting();
diff --git a/Mage.Server/src/main/java/mage/server/AuthorizedUser.java b/Mage.Server/src/main/java/mage/server/AuthorizedUser.java
index b9b754a698..f02b615e8c 100644
--- a/Mage.Server/src/main/java/mage/server/AuthorizedUser.java
+++ b/Mage.Server/src/main/java/mage/server/AuthorizedUser.java
@@ -14,7 +14,7 @@ import org.apache.shiro.crypto.hash.Hash;
@DatabaseTable(tableName = "authorized_user")
public class AuthorizedUser {
- @DatabaseField(indexName = "name_index")
+ @DatabaseField(indexName = "name_index", unique = true)
protected String name;
@DatabaseField
@@ -29,7 +29,7 @@ public class AuthorizedUser {
@DatabaseField
protected int hashIterations;
- @DatabaseField
+ @DatabaseField(indexName = "email_index", unique = true)
protected String email;
public AuthorizedUser() {
@@ -53,4 +53,8 @@ public class AuthorizedUser {
ByteSource.Util.bytes(Base64.decode(this.salt)), "");
return matcher.doCredentialsMatch(token, info);
}
+
+ public String getName() {
+ return this.name;
+ }
}
diff --git a/Mage.Server/src/main/java/mage/server/AuthorizedUserRepository.java b/Mage.Server/src/main/java/mage/server/AuthorizedUserRepository.java
index 3a56ec15a1..9507ce9a12 100644
--- a/Mage.Server/src/main/java/mage/server/AuthorizedUserRepository.java
+++ b/Mage.Server/src/main/java/mage/server/AuthorizedUserRepository.java
@@ -3,6 +3,7 @@ package mage.server;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
+import com.j256.ormlite.stmt.DeleteBuilder;
import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.support.ConnectionSource;
@@ -11,7 +12,6 @@ import com.j256.ormlite.table.TableUtils;
import java.io.File;
import java.sql.SQLException;
import java.util.List;
-import java.util.concurrent.Callable;
import mage.cards.repository.RepositoryUtil;
import org.apache.log4j.Logger;
import org.apache.shiro.crypto.RandomNumberGenerator;
@@ -54,25 +54,25 @@ public enum AuthorizedUserRepository {
public void add(final String userName, final String password, final String email) {
try {
- dao.callBatchTasks(new Callable