diff --git a/src/main/java/org/to/telegramfinalproject/UI/LoginController.java b/src/main/java/org/to/telegramfinalproject/UI/LoginController.java new file mode 100644 index 0000000..c26a534 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/LoginController.java @@ -0,0 +1,134 @@ +package org.to.telegramfinalproject.UI; + +import javafx.animation.PauseTransition; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.Parent; +import javafx.scene.control.*; +import javafx.stage.Stage; +import javafx.util.Duration; +import org.json.JSONObject; +import org.to.telegramfinalproject.Client.ClientConnection; +import org.to.telegramfinalproject.Database.userDatabase; +import org.to.telegramfinalproject.Models.User; +import org.to.telegramfinalproject.Security.PasswordHashing; + +import java.io.IOException; + +public class LoginController { + + @FXML private TextField usernameField; + + @FXML private PasswordField passwordField; + @FXML private TextField visiblePasswordField; + + @FXML private Button togglePasswordBtn; + @FXML private Label errorLabel; + + private ClientConnection connection; + private boolean passwordVisible = false; + + @FXML + public void initialize() { + // Sync hidden and visible password fields + visiblePasswordField.textProperty().bindBidirectional(passwordField.textProperty()); + + try { + connection = new ClientConnection("localhost", 12345); + } catch (Exception e) { + System.out.println("Could not connect to server: " + e.getMessage()); + } + } + + @FXML + private void togglePasswordVisibility() { + passwordVisible = !passwordVisible; + visiblePasswordField.setVisible(passwordVisible); + visiblePasswordField.setManaged(passwordVisible); + passwordField.setVisible(!passwordVisible); + passwordField.setManaged(!passwordVisible); + togglePasswordBtn.setText(passwordVisible ? "πŸ‘" : "πŸ‘"); + } + + @FXML + private void handleLogin() { + String username = usernameField.getText(); + String password = passwordField.getText(); + + // 1. Check for empty fields + if (username.isEmpty() || password.isEmpty()) { + showError("Please fill in all required fields."); + return; + } + + // 2. Check if username exists + userDatabase userDb = new userDatabase(); + if (!userDb.existsByUsername(username)) { + showError("This username doesn’t exist."); + return; + } + + // 3. Check if password is correct + User user = userDb.findByUsername(username); + if (!PasswordHashing.verify(password, user.getPassword())) { + showError("Incorrect password."); + return; + } + + // 4. Attempt to send to server + try { + JSONObject request = new JSONObject(); + request.put("action", "login"); + request.put("user_id", JSONObject.NULL); + request.put("username", username); + request.put("password", password); + request.put("profile_name", JSONObject.NULL); + + if (connection != null) { + connection.send(request.toString()); + String responseStr = connection.receive(); + JSONObject response = new JSONObject(responseStr); + System.out.println("Status: " + response.getString("status")); + System.out.println("Message: " + response.getString("message")); + + // Simulate successful login (since main.fxml isn’t ready) + Alert alert = new Alert(Alert.AlertType.INFORMATION, "Login successful!"); + alert.show(); + } + + } catch (Exception ex) { + showError("Unable to connect to server. Please try again later."); + } + } + + @FXML + private void switchToRegister() throws IOException { + switchScene("register_view.fxml"); + } + + private void switchScene(String fxmlFile) { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/" + fxmlFile)); + Parent root = loader.load(); + Stage stage = (Stage) usernameField.getScene().getWindow(); + stage.setScene(new Scene(root, 500, 700)); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + showError("Could not load scene: " + fxmlFile); + } + } + + private void showError(String message) { + errorLabel.setVisible(false); + errorLabel.setText(""); // Clear the label text + + PauseTransition pause = new PauseTransition(Duration.millis(50)); + pause.setOnFinished(event -> { + errorLabel.setText(message); + errorLabel.setVisible(true); + }); + pause.play(); + } +} \ No newline at end of file diff --git a/src/main/java/org/to/telegramfinalproject/UI/RegisterController.java b/src/main/java/org/to/telegramfinalproject/UI/RegisterController.java new file mode 100644 index 0000000..22bda84 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/RegisterController.java @@ -0,0 +1,160 @@ +package org.to.telegramfinalproject.UI; + +import javafx.animation.PauseTransition; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.*; +import javafx.stage.Stage; +import javafx.util.Duration; +import org.json.JSONObject; +import org.to.telegramfinalproject.Client.ClientConnection; +import org.to.telegramfinalproject.Database.userDatabase; + +import java.io.IOException; + +public class RegisterController { + + @FXML private TextField userIdField; + @FXML private TextField usernameField; + @FXML private TextField profileNameField; + + @FXML private PasswordField passwordField; + @FXML private TextField visiblePasswordField; + + @FXML private PasswordField confirmPasswordField; + @FXML private TextField visibleConfirmPasswordField; + + @FXML private Button togglePasswordBtn; + @FXML private Button toggleConfirmBtn; + + @FXML private Label errorLabel; + + private ClientConnection connection; + + private boolean passwordVisible = false; + private boolean confirmVisible = false; + + @FXML + public void initialize() { + // Sync password and confirm fields with their visible counterparts + visiblePasswordField.textProperty().bindBidirectional(passwordField.textProperty()); + visibleConfirmPasswordField.textProperty().bindBidirectional(confirmPasswordField.textProperty()); + + try { + connection = new ClientConnection("localhost", 12345); + } catch (Exception e) { + System.out.println("Could not connect to server: " + e.getMessage()); + } + } + + @FXML + private void togglePasswordVisibility() { + passwordVisible = !passwordVisible; + visiblePasswordField.setVisible(passwordVisible); + visiblePasswordField.setManaged(passwordVisible); + passwordField.setVisible(!passwordVisible); + passwordField.setManaged(!passwordVisible); + togglePasswordBtn.setText(passwordVisible ? "πŸ‘" : "πŸ‘"); + } + + @FXML + private void toggleConfirmPasswordVisibility() { + confirmVisible = !confirmVisible; + visibleConfirmPasswordField.setVisible(confirmVisible); + visibleConfirmPasswordField.setManaged(confirmVisible); + confirmPasswordField.setVisible(!confirmVisible); + confirmPasswordField.setManaged(!confirmVisible); + toggleConfirmBtn.setText(confirmVisible ? "πŸ‘" : "πŸ‘"); + } + + @FXML + private void handleRegister() { + String userID = userIdField.getText().trim(); + String username = usernameField.getText().trim(); + String profileName = profileNameField.getText().trim(); + String password = passwordField.getText(); + String confirmPass = confirmPasswordField.getText(); + + userDatabase userDb = new userDatabase(); + String passwordRegex = "\\b(?=[^\\s]*[A-Z])(?=[^\\s]*[a-z])(?=[^\\s]*\\d)(?=[^\\s]*[!@#$%^&*])[^\\s]{8,}\\b"; + + // 1. Empty fields + if (username.isEmpty() || profileName.isEmpty() || password.isEmpty() || confirmPass.isEmpty()) { + showError("Please fill in all required fields."); + return; + } + + // 2. Username exists + if (userDb.existsByUsername(username)) { + showError("This username is already taken."); + return; + } + + // 3. User ID exists (if entered) + if (!userID.isEmpty() && userDb.existsByUserId(userID)) { + showError("This user ID is already taken."); + return; + } + + // 4. Password mismatch + if (!password.equals(confirmPass)) { + showError("Passwords do not match."); + return; + } + + // 5. Weak password + if (!password.matches(passwordRegex)) { + showError("Password must be at least 8 characters, include a capital letter, a number, and a special character."); + return; + } + + // 6. Attempt registration + try { + JSONObject request = new JSONObject(); + request.put("action", "register"); + request.put("user_id", userID.isEmpty() ? JSONObject.NULL : userID); + request.put("username", username); + request.put("password", password); + request.put("profile_name", profileName); + connection.send(request.toString()); + + Alert alert = new Alert(Alert.AlertType.INFORMATION, "Registration successful!"); + alert.show(); + + } catch (Exception ex) { + showError("Failed to register. Please try again later."); + } + } + + @FXML + private void switchToLogin() throws IOException { + switchScene("login_view.fxml"); + } + + private void switchScene(String fxmlFile) { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/" + fxmlFile)); + Parent root = loader.load(); + Stage stage = (Stage) usernameField.getScene().getWindow(); // Or any node from your current scene + stage.setScene(new Scene(root, 500, 700)); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + showError("Could not load scene: " + fxmlFile); + } + } + + private void showError(String message) { + errorLabel.setVisible(false); + errorLabel.setText(""); // Clear the label text + + PauseTransition pause = new PauseTransition(Duration.millis(50)); + pause.setOnFinished(event -> { + errorLabel.setText(message); + errorLabel.setVisible(true); + }); + pause.play(); + } +} diff --git a/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java b/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java index 4903cc8..4ef6d2e 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java +++ b/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java @@ -81,20 +81,14 @@ public class RegisterForm { alert.show(); } else { - Alert alert = new Alert(Alert.AlertType.ERROR, "Password doesn't Strong enough"); + Alert alert = new Alert(Alert.AlertType.ERROR, "Password isn't Strong enough"); alert.show(); } - - - - }); backButton.setOnAction(e -> { switchScene("login_view.fxml"); }); - - } private void switchScene(String fxmlFile) { diff --git a/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java b/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java index db5330a..47a1970 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java +++ b/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java @@ -13,7 +13,7 @@ public class TelegramApplication extends Application { @Override public void start(Stage stage) throws IOException { FXMLLoader fxmlLoader = new FXMLLoader(TelegramApplication.class.getResource("/org/to/telegramfinalproject/Intro.fxml")); - Scene scene = new Scene(fxmlLoader.load(), 350, 500); + Scene scene = new Scene(fxmlLoader.load(), 1480, 820); stage.setTitle("Telegram"); stage.setScene(scene); stage.show(); diff --git a/src/main/java/org/to/telegramfinalproject/UI/login_view.java b/src/main/java/org/to/telegramfinalproject/UI/login_view.java index a7235ee..c89ef01 100644 --- a/src/main/java/org/to/telegramfinalproject/UI/login_view.java +++ b/src/main/java/org/to/telegramfinalproject/UI/login_view.java @@ -25,7 +25,7 @@ public class login_view { }); registerButton.setOnAction(e -> { - switchScene("RegisterForm.fxml"); + switchScene("register_view.fxml"); }); } diff --git a/src/main/resources/org/to/telegramfinalproject/Intro.fxml b/src/main/resources/org/to/telegramfinalproject/Intro.fxml index c138911..02ff71b 100644 --- a/src/main/resources/org/to/telegramfinalproject/Intro.fxml +++ b/src/main/resources/org/to/telegramfinalproject/Intro.fxml @@ -1,19 +1,31 @@ - + - - - + + + + + -