From 86ca58481f15ac892a7dd68521ec62d422b99b6b Mon Sep 17 00:00:00 2001 From: Partow Roshani Date: Wed, 4 Jun 2025 22:54:24 +0330 Subject: [PATCH] Login and Register with UI --- build.gradle | 2 + src/main/java/module-info.java | 2 + .../Client/ActionHandler.java | 70 ++++++ .../Client/ClientConnection.java | 30 +++ .../Client/TelegramClient.java | 84 +++++++ .../Database/ConnectionDb.java | 18 ++ .../Database/userDatabase.java | 207 ++++++++++++++++++ .../Models/RequestModel.java | 39 ++++ .../Models/ResponseModel.java | 19 ++ .../to/telegramfinalproject/Models/User.java | 93 ++++++++ .../Security/PasswordHashing.java | 30 +++ .../Server/AuthService.java | 46 ++++ .../Server/ClientHandler.java | 77 +++++++ .../Server/MainServer.java | 28 +++ .../to/telegramfinalproject/UI/LoginForm.java | 107 +++++++++ .../telegramfinalproject/UI/RegisterForm.java | 116 ++++++++++ .../UI/TelegramApplication.java | 26 +++ .../telegramfinalproject/UI/login_view.java | 48 ++++ .../to/telegramfinalproject/LoginForm.fxml | 40 ++++ .../to/telegramfinalproject/RegisterForm.fxml | 54 +++++ .../to/telegramfinalproject/login_view.fxml | 30 +++ 21 files changed, 1166 insertions(+) create mode 100644 src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java create mode 100644 src/main/java/org/to/telegramfinalproject/Client/ClientConnection.java create mode 100644 src/main/java/org/to/telegramfinalproject/Client/TelegramClient.java create mode 100644 src/main/java/org/to/telegramfinalproject/Database/ConnectionDb.java create mode 100644 src/main/java/org/to/telegramfinalproject/Database/userDatabase.java create mode 100644 src/main/java/org/to/telegramfinalproject/Models/RequestModel.java create mode 100644 src/main/java/org/to/telegramfinalproject/Models/ResponseModel.java create mode 100644 src/main/java/org/to/telegramfinalproject/Models/User.java create mode 100644 src/main/java/org/to/telegramfinalproject/Security/PasswordHashing.java create mode 100644 src/main/java/org/to/telegramfinalproject/Server/AuthService.java create mode 100644 src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java create mode 100644 src/main/java/org/to/telegramfinalproject/Server/MainServer.java create mode 100644 src/main/java/org/to/telegramfinalproject/UI/LoginForm.java create mode 100644 src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java create mode 100644 src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java create mode 100644 src/main/java/org/to/telegramfinalproject/UI/login_view.java create mode 100644 src/main/resources/org/to/telegramfinalproject/LoginForm.fxml create mode 100644 src/main/resources/org/to/telegramfinalproject/RegisterForm.fxml create mode 100644 src/main/resources/org/to/telegramfinalproject/login_view.fxml diff --git a/build.gradle b/build.gradle index 7c4e380..96bc6d1 100644 --- a/build.gradle +++ b/build.gradle @@ -40,9 +40,11 @@ dependencies { implementation('com.dlsc.formsfx:formsfx-core:11.6.0') { exclude group: 'org.openjfx' } + implementation 'org.postgresql:postgresql:42.7.3' implementation('net.synedra:validatorfx:0.5.0') { exclude group: 'org.openjfx' } + implementation 'org.json:json:20231013' implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1' implementation 'org.kordamp.bootstrapfx:bootstrapfx-core:0.4.0' implementation('eu.hansolo:tilesfx:21.0.3') { diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 4d8e706..f20151f 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -9,6 +9,8 @@ module org.to.telegramfinalproject { requires org.kordamp.ikonli.javafx; requires org.kordamp.bootstrapfx.core; requires eu.hansolo.tilesfx; + requires org.json; + requires java.sql; opens org.to.telegramfinalproject to javafx.fxml; exports org.to.telegramfinalproject; } \ No newline at end of file diff --git a/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java b/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java new file mode 100644 index 0000000..5f9d192 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java @@ -0,0 +1,70 @@ +package org.to.telegramfinalproject.Client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Scanner; +import org.json.JSONObject; + +public class ActionHandler { + private final PrintWriter out; + private final BufferedReader in; + private final Scanner scanner; + + public ActionHandler(PrintWriter out, BufferedReader in, Scanner scanner) { + this.out = out; + this.in = in; + this.scanner = scanner; + } + + public void loginHandler() { + System.out.println("Login form: \n"); + System.out.println("Username: "); + String username = this.scanner.nextLine(); + System.out.println("Password: "); + String password = this.scanner.nextLine(); + 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); + this.send(request); + } + + public void register() { + System.out.println("Register form: \n"); + System.out.println("Username: "); + String username = this.scanner.nextLine(); + System.out.println("User id: "); + String user_id = this.scanner.nextLine(); + System.out.println("Password: "); + String password = this.scanner.nextLine(); + System.out.println("Profile name: "); + String profile_name = this.scanner.nextLine(); + JSONObject request = new JSONObject(); + request.put("action", "register"); + request.put("user_id", user_id); + request.put("username", username); + request.put("password", password); + request.put("profile_name", profile_name); + this.send(request); + } + + private void send(JSONObject request) { + try { + this.out.println(request.toString()); + String responseText = this.in.readLine(); + if (responseText != null) { + JSONObject response = new JSONObject(responseText); + System.out.println("Server response: " + response.getString("message")); + } else { + System.out.println("No response from server."); + } + } catch (IOException e) { + System.err.println("Error: " + e.getMessage()); + } + + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/Client/ClientConnection.java b/src/main/java/org/to/telegramfinalproject/Client/ClientConnection.java new file mode 100644 index 0000000..870796d --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Client/ClientConnection.java @@ -0,0 +1,30 @@ +package org.to.telegramfinalproject.Client; + +import java.io.*; +import java.net.Socket; + +public class ClientConnection { + private Socket socket; + private BufferedReader in; + private PrintWriter out; + + public ClientConnection(String host, int port) throws IOException { + this.socket = new Socket(host, port); + this.in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + this.out = new PrintWriter(socket.getOutputStream(), true); + } + + public void send(String request) { + out.println(request); + } + + public String receive() throws IOException { + return in.readLine(); + } + + public void close() throws IOException { + socket.close(); + in.close(); + out.close(); + } +} \ No newline at end of file diff --git a/src/main/java/org/to/telegramfinalproject/Client/TelegramClient.java b/src/main/java/org/to/telegramfinalproject/Client/TelegramClient.java new file mode 100644 index 0000000..686c02d --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Client/TelegramClient.java @@ -0,0 +1,84 @@ +package org.to.telegramfinalproject.Client; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; +import java.util.Scanner; + +public class TelegramClient { + private static final String SERVER_HOST = "localhost"; + private static final int SERVER_PORT = 12345; + private Socket socket; + private BufferedReader in; + private PrintWriter out; + private final Scanner scanner; + ActionHandler handler = null; + + public TelegramClient() { + this.scanner = new Scanner(System.in); + } + + public void start() { + try { + this.socket = new Socket(SERVER_HOST, SERVER_PORT); + this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); + this.out = new PrintWriter(this.socket.getOutputStream(), true); + System.out.println(" Connected to Telegram Server"); + this.handler = new ActionHandler(this.out, this.in, this.scanner); + this.showMainMenu(); + } catch (IOException e) { + System.err.println("Error connecting to server: " + e.getMessage()); + } + + } + + private void showMainMenu() { + while(true) { + System.out.println("Main Menu:"); + System.out.println("1. Register"); + System.out.println("2. Login"); + System.out.println("3. Exit"); + System.out.print("Choose an option: "); + switch (this.scanner.nextLine()) { + case "1": + this.handler.register(); + break; + case "2": + this.handler.loginHandler(); + break; + case "3": + System.out.println(" Disconnecting..."); + + try { + if (this.socket != null) { + this.socket.close(); + } + + if (this.in != null) { + this.in.close(); + } + + if (this.out != null) { + this.out.close(); + } + + System.out.println("Disconnected."); + } catch (IOException e) { + System.err.println(" Error closing connection: " + e.getMessage()); + } + + return; + default: + System.out.println("Invalid choice. Please try again."); + } + } + } + + public static void main(String[] args) { + TelegramClient client = new TelegramClient(); + client.start(); + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/Database/ConnectionDb.java b/src/main/java/org/to/telegramfinalproject/Database/ConnectionDb.java new file mode 100644 index 0000000..f8a264b --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Database/ConnectionDb.java @@ -0,0 +1,18 @@ +package org.to.telegramfinalproject.Database; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class ConnectionDb { + private static final String JDBC_URL = "jdbc:postgresql://localhost:5432/Telegramdb"; + private static final String USERNAME = "postgres"; + private static final String PASSWORD = "Partow@1384"; + + public ConnectionDb() { + } + + public static Connection connect() throws SQLException { + return DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD); + } +} \ No newline at end of file diff --git a/src/main/java/org/to/telegramfinalproject/Database/userDatabase.java b/src/main/java/org/to/telegramfinalproject/Database/userDatabase.java new file mode 100644 index 0000000..b89596e --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Database/userDatabase.java @@ -0,0 +1,207 @@ +package org.to.telegramfinalproject.Database; + + +import org.to.telegramfinalproject.Models.User; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class userDatabase { + public userDatabase() { + } + + private Connection getConnection() throws SQLException { + return ConnectionDb.connect(); + } + + public User findByUserId(String userId) { + String query = "SELECT * FROM users WHERE user_id = ?"; + + try { + User var6; + try (Connection conn = this.getConnection()) { + try (PreparedStatement stmt = conn.prepareStatement(query)) { + stmt.setString(1, userId); + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) { + return null; + } + + var6 = this.extractUser(rs); + } + } + + return var6; + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } + + public User findByUsername(String username) { + String query = "SELECT * FROM users WHERE username = ?"; + + try { + User var6; + try (Connection conn = this.getConnection()) { + try (PreparedStatement stmt = conn.prepareStatement(query)) { + stmt.setString(1, username); + ResultSet rs = stmt.executeQuery(); + if (!rs.next()) { + return null; + } + + var6 = this.extractUser(rs); + } + } + + return var6; + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } + + public boolean existsByUsername(String username) { + String query = "SELECT 1 FROM users WHERE username = ?"; + + try { + boolean var6; + try ( + Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query); + ) { + stmt.setString(1, username); + ResultSet rs = stmt.executeQuery(); + var6 = rs.next(); + } + + return var6; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + public boolean existsByUserId(String user_id) { + String query = "SELECT 1 FROM users WHERE user_id = ?"; + + try { + boolean var6; + try ( + Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query); + ) { + stmt.setString(1, user_id); + ResultSet rs = stmt.executeQuery(); + var6 = rs.next(); + } + + return var6; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + public boolean save(User user) { + String query = "INSERT INTO users (user_id, internal_uuid, username, password, profile_name) VALUES (?, ?, ?, ?, ?)"; + + try { + boolean var5; + try ( + Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query); + ) { + stmt.setString(1, user.getUser_id()); + stmt.setObject(2, user.getInternal_uuid()); + stmt.setString(3, user.getUsername()); + stmt.setString(4, user.getPassword()); + stmt.setString(5, user.getProfile_name()); + var5 = stmt.executeUpdate() > 0; + } + + return var5; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + public boolean updateByUUID(UUID uuid, User user) { + String query = "UPDATE users SET user_id=?, username=?, password=?, profile_name=?, bio=?, image_url=?, status=?, last_seen=? WHERE internal_uuid=?"; + + try { + boolean var6; + try ( + Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query); + ) { + stmt.setString(1, user.getUser_id()); + stmt.setString(2, user.getUsername()); + stmt.setString(3, user.getPassword()); + stmt.setString(4, user.getProfile_name()); + stmt.setString(5, user.getBio()); + stmt.setString(6, user.getImage_url()); + stmt.setString(7, user.getStatus()); + stmt.setObject(8, user.getLast_seen()); + stmt.setObject(9, uuid); + var6 = stmt.executeUpdate() > 0; + } + + return var6; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + + public List getAll() { + List users = new ArrayList(); + String query = "SELECT * FROM users"; + + try ( + Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query); + ResultSet rs = stmt.executeQuery(); + ) { + while(rs.next()) { + users.add(this.extractUser(rs)); + } + } catch (SQLException e) { + e.printStackTrace(); + } + + return users; + } + + private User extractUser(ResultSet rs) throws SQLException { + return new User(rs.getString("user_id"), UUID.fromString(rs.getString("internal_uuid")), rs.getString("username"), rs.getString("password"), rs.getString("profile_name")); + } + + public boolean deleteByUUID(UUID uuid) { + String query = "DELETE FROM users WHERE internal_uuid = ?"; + + try { + boolean var5; + try ( + Connection conn = this.getConnection(); + PreparedStatement stmt = conn.prepareStatement(query); + ) { + stmt.setObject(1, uuid); + var5 = stmt.executeUpdate() > 0; + } + + return var5; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/Models/RequestModel.java b/src/main/java/org/to/telegramfinalproject/Models/RequestModel.java new file mode 100644 index 0000000..d460e5c --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Models/RequestModel.java @@ -0,0 +1,39 @@ +package org.to.telegramfinalproject.Models; + +public class RequestModel { + private String action; + private String user_id; + private String username; + private String password; + private String profile_name; + + public RequestModel(String action, String user_id, String username, String password, String profile_name) { + this.action = action; + this.user_id = user_id; + this.username = username; + this.password = password; + this.profile_name = profile_name; + } + + public String getAction() { + return this.action; + } + + public String getUser_id() { + return this.user_id; + } + + public String getUsername() { + return this.username; + } + + public String getPassword() { + return this.password; + } + + public String getProfile_name() { + return this.profile_name; + } +} + + diff --git a/src/main/java/org/to/telegramfinalproject/Models/ResponseModel.java b/src/main/java/org/to/telegramfinalproject/Models/ResponseModel.java new file mode 100644 index 0000000..9d6ab0f --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Models/ResponseModel.java @@ -0,0 +1,19 @@ +package org.to.telegramfinalproject.Models; + +public class ResponseModel { + private String status; + private String message; + + public ResponseModel(String status, String message) { + this.status = status; + this.message = message; + } + + public String getStatus() { + return this.status; + } + + public String getMessage() { + return this.message; + } +} diff --git a/src/main/java/org/to/telegramfinalproject/Models/User.java b/src/main/java/org/to/telegramfinalproject/Models/User.java new file mode 100644 index 0000000..2dc8e86 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Models/User.java @@ -0,0 +1,93 @@ +package org.to.telegramfinalproject.Models; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class User { + private String user_id; + private UUID internal_uuid; + private String username; + private String password; + private String profile_name; + private String bio; + private String image_url; + private String status; + private LocalDateTime last_seen; + + public User(String user_id, UUID internal_uuid, String username, String password, String profile_name) { + this.user_id = user_id; + this.internal_uuid = internal_uuid; + this.username = username; + this.password = password; + this.profile_name = profile_name; + } + + public void setUser_id(String user_id) { + this.user_id = user_id; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setProfile_name(String profile_name) { + this.profile_name = profile_name; + } + + public void setBio(String bio) { + this.bio = bio; + } + + public void setImage_url(String image_url) { + this.image_url = image_url; + } + + public void setStatus(String status) { + this.status = status; + } + + public void setLast_seen(LocalDateTime last_seen) { + this.last_seen = last_seen; + } + + public UUID getInternal_uuid() { + return this.internal_uuid; + } + + public String getUser_id() { + return this.user_id; + } + + public String getUsername() { + return this.username; + } + + public String getPassword() { + return this.password; + } + + public String getProfile_name() { + return this.profile_name; + } + + public String getBio() { + return this.bio; + } + + public String getImage_url() { + return this.image_url; + } + + public String getStatus() { + return this.status; + } + + public LocalDateTime getLast_seen() { + return this.last_seen; + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/Security/PasswordHashing.java b/src/main/java/org/to/telegramfinalproject/Security/PasswordHashing.java new file mode 100644 index 0000000..ae1b916 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Security/PasswordHashing.java @@ -0,0 +1,30 @@ +package org.to.telegramfinalproject.Security; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class PasswordHashing { + public PasswordHashing() { + } + + public static String hash(String password) { + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] hashedBytes = md.digest(password.getBytes()); + StringBuilder sb = new StringBuilder(); + + for(byte b : hashedBytes) { + sb.append(String.format("%02x", b)); + } + + return sb.toString(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("Hashing algorithm not found!", e); + } + } + + public static boolean verify(String password, String hashedPasswordFromDB) { + return hash(password).equals(hashedPasswordFromDB); + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/Server/AuthService.java b/src/main/java/org/to/telegramfinalproject/Server/AuthService.java new file mode 100644 index 0000000..587361b --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Server/AuthService.java @@ -0,0 +1,46 @@ +package org.to.telegramfinalproject.Server; + +import java.util.UUID; +import org.to.telegramfinalproject.Database.userDatabase; +import org.to.telegramfinalproject.Models.User; +import org.to.telegramfinalproject.Security.PasswordHashing; + +public class AuthService { + private final userDatabase userDb = new userDatabase(); + + public AuthService() { + } + + public boolean register(String user_id, String username, String password, String profile_name) { + if (!this.userDb.existsByUsername(username) && !this.userDb.existsByUserId(user_id)) { + String passwordRegex = "\\b(?=[^\\s]*[A-Z])(?=[^\\s]*[a-z])(?=[^\\s]*\\d)(?=[^\\s]*[!@#$%^&*])[^\\s]{8,}\\b"; + if (!password.matches(passwordRegex)) { + System.out.println("Password doesn't Valid(At list one capital and one special char(!@#$%^&*), minimum 8 char "); + return false; + } else { + UUID uuid = UUID.randomUUID(); + password = PasswordHashing.hash(password); + User user = new User(user_id, uuid, username, password, profile_name); + return this.userDb.save(user); + } + } else { + System.out.println("Username/ user id is already taken"); + return false; + } + } + + public User login(String username, String password) { + User user = this.userDb.findByUsername(username); + if (user == null) { + System.out.println("User not found."); + return null; + } else if (!PasswordHashing.verify(password, user.getPassword())) { + System.out.println("Incorrect password"); + return null; + } else { + return user; + } + } +} + + diff --git a/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java new file mode 100644 index 0000000..6feb754 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java @@ -0,0 +1,77 @@ +package org.to.telegramfinalproject.Server; + +import org.json.JSONObject; +import org.to.telegramfinalproject.Models.RequestModel; +import org.to.telegramfinalproject.Models.ResponseModel; +import org.to.telegramfinalproject.Models.User; + +import java.io.*; +import java.net.Socket; + +public class ClientHandler implements Runnable { + private final Socket socket; + private final AuthService authService = new AuthService(); + + public ClientHandler(Socket socket) { + this.socket = socket; + } + + @Override + public void run() { + try ( + BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + PrintWriter out = new PrintWriter(socket.getOutputStream(), true) + ) { + String inputLine; + while ((inputLine = in.readLine()) != null) { + JSONObject requestJson = new JSONObject(inputLine); + + RequestModel request = new RequestModel( + requestJson.optString("action"), + requestJson.optString("user_id"), + requestJson.optString("username"), + requestJson.optString("password"), + requestJson.optString("profile_name") + ); + + ResponseModel response; + + switch (request.getAction()) { + case "register": + boolean registered = authService.register( + request.getUser_id(), + request.getUsername(), + request.getPassword(), + request.getProfile_name() + ); + response = registered + ? new ResponseModel("success", "Registration successful.") + : new ResponseModel("error", "Registration failed."); + break; + + case "login": + User user = authService.login(request.getUsername(), request.getPassword()); + response = (user != null) + ? new ResponseModel("success", "Welcome " + user.getProfile_name()) + : new ResponseModel("error", "Login failed."); + break; + + case "logout": + response = new ResponseModel("success", "Logged out."); + break; + + default: + response = new ResponseModel("error", "Unknown action: " + request.getAction()); + } + + JSONObject responseJson = new JSONObject(); + responseJson.put("status", response.getStatus()); + responseJson.put("message", response.getMessage()); + out.println(responseJson.toString()); + } + + } catch (IOException e) { + System.out.println("Connection with client lost."); + } + } +} diff --git a/src/main/java/org/to/telegramfinalproject/Server/MainServer.java b/src/main/java/org/to/telegramfinalproject/Server/MainServer.java new file mode 100644 index 0000000..57f066a --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/Server/MainServer.java @@ -0,0 +1,28 @@ +package org.to.telegramfinalproject.Server; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +public class MainServer { + private static final int PORT = 12345; + + public static void main(String[] args) { + try (ServerSocket serverSocket = new ServerSocket(PORT)) { + System.out.println("Server started on port " + PORT); + + while (true) { + Socket clientSocket = serverSocket.accept(); + System.out.println("New client connected: " + clientSocket.getInetAddress()); + + ClientHandler handler = new ClientHandler(clientSocket); + new Thread(handler).start(); + } + + } catch (IOException e) { + System.err.println("Server error: " + e.getMessage()); + e.printStackTrace(); + } + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/UI/LoginForm.java b/src/main/java/org/to/telegramfinalproject/UI/LoginForm.java new file mode 100644 index 0000000..79ae18e --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/LoginForm.java @@ -0,0 +1,107 @@ +package org.to.telegramfinalproject.UI; + + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.PasswordField; +import javafx.scene.control.TextField; +import javafx.stage.Stage; +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 LoginForm { + + @FXML + private Button loginButton; + @FXML + private Button backButton; + @FXML private TextField usernameField; + @FXML private PasswordField passwordField; + + private ClientConnection connection; + + @FXML + public void initialize() { + + try { + connection = new ClientConnection("localhost", 12345); + } catch (Exception e) { + System.out.println("Could not connect to server: " + e.getMessage()); + } + + loginButton.setOnAction(e -> { + String username = usernameField.getText(); + String password = passwordField.getText(); + + 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()); + } + userDatabase userDb = new userDatabase(); + User user = userDb.findByUsername(username); + + if(!userDb.existsByUsername(username)){ + Alert alert = new Alert(Alert.AlertType.ERROR, "Invalid username"); + alert.show(); + } + else if(!PasswordHashing.verify(password,user.getPassword())){ + Alert alert = new Alert(Alert.AlertType.ERROR, "Invalid password"); + alert.show(); + } + else if(!PasswordHashing.verify(password,user.getPassword()) && !userDb.existsByUsername(username)){ + Alert alert = new Alert(Alert.AlertType.ERROR, "Invalid password and username"); + alert.show(); + } + else{ + try { + String responseStr = connection.receive(); + JSONObject response = new JSONObject(responseStr); + System.out.println("Status: " + response.getString("status")); + System.out.println("Message: " + response.getString("message")); + Alert alert = new Alert(Alert.AlertType.INFORMATION, " Message: " + response.getString("message")); + alert.show(); + } catch (Exception ex) { + Alert alert = new Alert(Alert.AlertType.ERROR, "Error receiving response: " + ex.getMessage()); + alert.show(); + } + } + }); + + backButton.setOnAction(e -> { + 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) backButton.getScene().getWindow(); + stage.setScene(new Scene(root)); + stage.show(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java b/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java new file mode 100644 index 0000000..4903cc8 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/RegisterForm.java @@ -0,0 +1,116 @@ +package org.to.telegramfinalproject.UI; + + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.control.Button; +import javafx.scene.control.PasswordField; +import javafx.scene.control.TextField; +import javafx.stage.Stage; +import org.json.JSONObject; +import org.to.telegramfinalproject.Client.ClientConnection; +import org.to.telegramfinalproject.Database.userDatabase; + +import java.io.IOException; + +public class RegisterForm { + @FXML + private Button submitButton; + @FXML + private Button backButton; + @FXML private TextField userIdField; + @FXML private TextField usernameField; + @FXML private TextField profileNameField; + @FXML private PasswordField passwordField; + @FXML private PasswordField confirmPasswordField; + + + + private ClientConnection connection; + + @FXML + public void initialize() { + + try { + connection = new ClientConnection("localhost", 12345); + } catch (Exception e) { + System.out.println("Could not connect to server: " + e.getMessage()); + } + + submitButton.setOnAction(e -> { + String userID = userIdField.getText(); + String username = usernameField.getText(); + String profile_name = profileNameField.getText(); + String password = passwordField.getText(); + String confirmPass =confirmPasswordField.getText(); + JSONObject request = new JSONObject(); + String passwordRegex = "\\b(?=[^\\s]*[A-Z])(?=[^\\s]*[a-z])(?=[^\\s]*\\d)(?=[^\\s]*[!@#$%^&*])[^\\s]{8,}\\b"; + + userDatabase userDb = new userDatabase(); + if(password.equals(confirmPass) && password.matches(passwordRegex) && !userDb.existsByUserId(userID)&& !userDb.existsByUsername(username)){ + try { + request.put("action", "register"); + request.put("user_id", userID); + request.put("username", username); + request.put("password", password); + request.put("profile_name", profile_name); + connection.send(request.toString()); + Alert alert = new Alert(Alert.AlertType.INFORMATION, "Registration is successful"); + alert.show(); + + } catch (Exception ex) { + Alert alert = new Alert(Alert.AlertType.ERROR, "Error receiving response: " + ex.getMessage()); + alert.show(); + } + + } + else if(!password.equals(confirmPass) && password.matches(passwordRegex)) { + Alert alert = new Alert(Alert.AlertType.ERROR, "Password doesn't match"); + alert.show(); + } + else if(userDb.existsByUserId(userID)) + { + Alert alert = new Alert(Alert.AlertType.ERROR, "User ID is already exist"); + alert.show(); + } + else if(userDb.existsByUsername(username)){ + Alert alert = new Alert(Alert.AlertType.ERROR, "Username is already exist"); + alert.show(); + } + else { + Alert alert = new Alert(Alert.AlertType.ERROR, "Password doesn't Strong enough"); + alert.show(); + } + + + + + }); + + backButton.setOnAction(e -> { + 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) backButton.getScene().getWindow(); + stage.setScene(new Scene(root)); + stage.show(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} + diff --git a/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java b/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java new file mode 100644 index 0000000..1119cb8 --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/TelegramApplication.java @@ -0,0 +1,26 @@ +package org.to.telegramfinalproject.UI; + + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.stage.Stage; +import org.to.telegramfinalproject.HelloApplication; + +import java.io.IOException; + +public class TelegramApplication extends Application { + @Override + public void start(Stage stage) throws IOException { + FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("login_view.fxml")); + Scene scene = new Scene(fxmlLoader.load(), 320, 240); + stage.setTitle("Hello!"); + stage.setScene(scene); + stage.show(); + } + public static void main(String[] args) { + launch(); + } + +} + diff --git a/src/main/java/org/to/telegramfinalproject/UI/login_view.java b/src/main/java/org/to/telegramfinalproject/UI/login_view.java new file mode 100644 index 0000000..a7235ee --- /dev/null +++ b/src/main/java/org/to/telegramfinalproject/UI/login_view.java @@ -0,0 +1,48 @@ +package org.to.telegramfinalproject.UI; + +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.stage.Stage; + +import java.io.IOException; + +public class login_view { + + @FXML + private Button loginButton; + + @FXML + private Button registerButton; + + @FXML + public void initialize() { + + loginButton.setOnAction(e -> { + switchScene("LoginForm.fxml"); + }); + + registerButton.setOnAction(e -> { + switchScene("RegisterForm.fxml"); + }); + } + + private void switchScene(String fxmlFile) { + try { + + FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/to/telegramfinalproject/" + fxmlFile)); + Parent root = loader.load(); + + + Stage stage = (Stage) loginButton.getScene().getWindow(); + stage.setScene(new Scene(root)); + stage.show(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} + diff --git a/src/main/resources/org/to/telegramfinalproject/LoginForm.fxml b/src/main/resources/org/to/telegramfinalproject/LoginForm.fxml new file mode 100644 index 0000000..3c3430e --- /dev/null +++ b/src/main/resources/org/to/telegramfinalproject/LoginForm.fxml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/org/to/telegramfinalproject/RegisterForm.fxml b/src/main/resources/org/to/telegramfinalproject/RegisterForm.fxml new file mode 100644 index 0000000..4f3f7dd --- /dev/null +++ b/src/main/resources/org/to/telegramfinalproject/RegisterForm.fxml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + +