Merge pull request #2 from PartowRoshani/Login/Register

Login/register
This commit is contained in:
2025-06-08 16:45:18 +03:30
committed by GitHub
38 changed files with 2693 additions and 0 deletions
+2
View File
@@ -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;
}
@@ -0,0 +1,218 @@
package org.to.telegramfinalproject.Client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.json.JSONArray;
import org.json.JSONObject;
import org.to.telegramfinalproject.Models.ChatEntry;
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);
}
public void search(){
System.out.print("Enter keyword to search: ");
String keyword = scanner.nextLine();
JSONObject request = new JSONObject();
request.put("action", "search");
request.put("keyword", keyword);
send(request);
}
private void send(JSONObject request) {
try {
if (!request.has("action") || request.isNull("action")) {
System.err.println("Error: Request does not contain 'action'.");
return;
}
String action = request.getString("action");
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"));
String status = response.getString("status");
if (status.equals("success") && response.has("data") && !response.isNull("data")) {
switch (action) {
case "login":
case "register":
Session.currentUser = response.getJSONObject("data");
JSONArray chatListJson = Session.currentUser.getJSONArray("chat_list");
List<ChatEntry> chatList = new ArrayList<>();
for (Object obj : chatListJson) {
JSONObject chat = (JSONObject) obj;
ChatEntry entry = new ChatEntry(
chat.getString("id"),
chat.getString("name"),
chat.getString("image_url"),
chat.getString("type"),
chat.isNull("last_message_time") ? null : LocalDateTime.parse(chat.getString("last_message_time"))
);
chatList.add(entry);
}
Session.chatList = chatList;
break;
case "search":
JSONArray results = response.getJSONObject("data").getJSONArray("results");
if (results.isEmpty()) {
System.out.println("No results found.");
} else {
System.out.println("\nSearch Results:");
for (Object obj : results) {
JSONObject item = (JSONObject) obj;
System.out.println("- [" + item.getString("type") + "] " + item.getString("name") + " (ID: " + item.getString("id") + ")");
}
}
break;
case "get_messages":
break;
}
}
} else {
System.out.println("No response from server.");
}
} catch (IOException e) {
System.err.println("Error while communicating with server: " + e.getMessage());
} catch (Exception e) {
System.err.println("Client error: " + e.getMessage());
e.printStackTrace();
}
}
public void userMenu() {
while (true) {
System.out.println("\nUser Menu:");
System.out.println("1. Show chat list");
System.out.println("2. Search");
System.out.println("3. Logout");
System.out.print("Choose an option: ");
String choice = scanner.nextLine();
switch (choice) {
case "1":
showChatListAndSelect();
break;
case "2" :
search();
break;
case "3":
Session.currentUser = null;
Session.chatList = null;
System.out.println("Logged out.");
return;
default:
System.out.println("Invalid choice.");
}
}
}
public void showChatListAndSelect() {
if (Session.chatList == null || Session.chatList.isEmpty()) {
System.out.println("No chats available.");
return;
}
System.out.println("\nYour Chats:");
for (int i = 0; i < Session.chatList.size(); i++) {
ChatEntry entry = Session.chatList.get(i);
String time = entry.getLastMessageTime() == null ? "No messages yet" : entry.getLastMessageTime().toString();
System.out.println((i + 1) + ". [" + entry.getType() + "] " + entry.getName() + " - Last: " + time);
}
System.out.print("Select a chat by number: ");
int choice = Integer.parseInt(scanner.nextLine()) - 1;
if (choice < 0 || choice >= Session.chatList.size()) {
System.out.println("Invalid selection.");
return;
}
ChatEntry selected = Session.chatList.get(choice);
openChat(selected);
}
private void openChat(ChatEntry chat) {
JSONObject request = new JSONObject();
request.put("action", "get_messages");
request.put("receiver_id", chat.getId());
request.put("receiver_type", chat.getType());
send(request);
}
}
@@ -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();
}
}
@@ -0,0 +1,13 @@
package org.to.telegramfinalproject.Client;
import org.json.JSONObject;
import org.to.telegramfinalproject.Models.ChatEntry;
import java.util.List;
// method for save data from server response
public class Session {
public static JSONObject currentUser;
public static List<ChatEntry> chatList;
}
@@ -0,0 +1,91 @@
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();
if (Session.currentUser != null) {
System.out.println("Login successful.");
this.handler.userMenu();
} else {
System.out.println("Login failed.");
}
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();
}
}
@@ -0,0 +1,78 @@
package org.to.telegramfinalproject.Database;
import org.to.telegramfinalproject.Models.Channel;
import org.to.telegramfinalproject.Models.Group;
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 ChannelDatabase {
public static List<Channel> getChannelsByUser(UUID internalUuid) {
List<Channel> channels = new ArrayList<>();
String sql = """
SELECT c.* FROM channels c
JOIN channel_subscribers cs ON c.internal_uuid = cs.channel_id
WHERE cs.user_id = ?
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, internalUuid);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Channel channel = new Channel();
channel.setInternal_uuid(UUID.fromString(rs.getString("internal_uuid")));
channel.setChannel_id(rs.getString("channel_id"));
channel.setChannel_name(rs.getString("channel_name"));
channel.setCreator_id(UUID.fromString(rs.getString("creator_id")));
channel.setImage_url(rs.getString("image_url"));
channel.setDescription(rs.getString("description"));
channel.setCreated_at(rs.getTimestamp("created_at").toLocalDateTime());
channels.add(channel);
}
} catch (SQLException e) {
e.printStackTrace();
}
return channels;
}
public static List<Channel> searchChannels(String keyword) {
List<Channel> result = new ArrayList<>();
String sql = "SELECT * FROM channels WHERE channel_name ILIKE ? OR channel_id ILIKE ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "%" + keyword + "%");
stmt.setString(2, keyword);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Channel channel = new Channel(
UUID.fromString(rs.getString("internal_uuid")),
rs.getString("channel_name"),
UUID.fromString(rs.getString("creator_id")),
rs.getTimestamp("created_at").toLocalDateTime()
);
channel.setChannel_id(rs.getString("channel_id"));
channel.setImage_url(rs.getString("image_url"));
channel.setDescription(rs.getString("description"));
result.add(channel);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}
@@ -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/Telegram";
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);
}
}
@@ -0,0 +1,158 @@
package org.to.telegramfinalproject.Database;
import org.to.telegramfinalproject.Models.Contact;
import org.to.telegramfinalproject.Models.User;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class ContactDatabase {
public ContactDatabase(){}
private static Connection getConnection() throws SQLException {
return ConnectionDb.connect();
}
public boolean addContact(UUID user_id, UUID contact_id) {
String sql = "INSERT INTO contacts (user_id, contact_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setObject(2,contact_id);
return stmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public boolean removeContact(UUID user_id, UUID contact_id) {
String sql = "DELETE FROM contacts WHERE user_id = ? AND contact_id = ?";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setObject(2, contact_id);
return stmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public boolean blockContact(UUID user_id, UUID contact_id) {
String sql = "UPDATE contacts SET is_blocked = TRUE WHERE user_id = ? AND contact_id = ?";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setObject(2, contact_id);
return stmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public boolean unblockContact(UUID user_id, UUID contact_id) {
String sql = "UPDATE contacts SET is_blocked = FALSE WHERE user_id = ? AND contact_id = ?";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setObject(2, contact_id);
return stmt.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static List<Contact> getContacts(UUID user_id) {
List<Contact> contacts = new ArrayList<>();
String sql = "SELECT * FROM contacts WHERE user_id = ?";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
UUID contactId = (UUID) rs.getObject("contact_id");
boolean isBlocked = rs.getBoolean("is_blocked");
Timestamp addedAt = rs.getTimestamp("added_at");
Contact contact = new Contact(user_id, contactId);
contact.setIs_blocked(isBlocked);
contact.setAdd_at(addedAt.toLocalDateTime());
contacts.add(contact);
}
} catch (SQLException e) {
e.printStackTrace();
}
return contacts;
}
public boolean existsContact(UUID user_id, UUID contact_id) {
String sql = "SELECT 1 FROM contacts WHERE user_id = ? AND contact_id = ? LIMIT 1"; // stop searching when find the first item in DB(LIMIT 1)
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setObject(2, contact_id);
ResultSet rs = stmt.executeQuery();
return rs.next();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public boolean isBlocked(UUID user_id, UUID contact_id) {
String sql = "SELECT is_blocked FROM contacts WHERE user_id = ? AND contact_id = ?";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setObject(2, contact_id);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return rs.getBoolean("is_blocked");
}
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
public List<Contact> searchContacts(UUID user_id, String searchTerm) {
List<Contact> results = new ArrayList<>(); //ILIKE case-insensitive
String sql = """
SELECT c.contact_id, c.added_at, c.is_blocked
FROM contacts c
JOIN users u ON c.contact_id = u.internal_uuid
WHERE c.user_id = ? AND (u.user_id ILIKE ? OR u.profile_name ILIKE ?)
""";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setString(2, "%" + searchTerm + "%");
stmt.setString(3, "%" + searchTerm + "%");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
UUID contactId = (UUID) rs.getObject("contact_id");
boolean isBlocked = rs.getBoolean("is_blocked");
Timestamp addedAt = rs.getTimestamp("added_at");
Contact contact = new Contact(user_id, contactId);
contact.setIs_blocked(isBlocked);
contact.setAdd_at(addedAt.toLocalDateTime());
results.add(contact);
}
} catch (SQLException e) {
e.printStackTrace();
}
return results;
}
}
@@ -0,0 +1,80 @@
package org.to.telegramfinalproject.Database;
import org.to.telegramfinalproject.Models.Group;
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 GroupDatabase {
public static List<Group> getGroupsByUser(UUID internalUuid) {
List<Group> groups = new ArrayList<>();
String sql = """
SELECT g.* FROM groups g
JOIN group_members gm ON g.internal_uuid = gm.group_id
WHERE gm.user_id = ?
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, internalUuid);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Group group = new Group();
group.setInternal_uuid(UUID.fromString(rs.getString("internal_uuid")));
group.setGroup_id(rs.getString("group_id"));
group.setGroup_name(rs.getString("group_name"));
group.setCreator_id(UUID.fromString(rs.getString("creator_id")));
group.setImage_url(rs.getString("image_url"));
group.setDescription(rs.getString("description"));
group.setCreated_at(rs.getTimestamp("created_at").toLocalDateTime());
groups.add(group);
}
} catch (SQLException e) {
e.printStackTrace();
}
return groups;
}
public static List<Group> searchGroups(String keyword) {
List<Group> result = new ArrayList<>();
String sql = "SELECT * FROM groups WHERE group_name ILIKE ? OR group_id ILIKE ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, "%" + keyword + "%");
stmt.setString(2, keyword);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
Group group = new Group(
UUID.fromString(rs.getString("internal_uuid")),
rs.getString("group_name"),
UUID.fromString(rs.getString("creator_id")),
rs.getTimestamp("created_at").toLocalDateTime()
);
group.setGroup_id(rs.getString("group_id"));
group.setImage_url(rs.getString("image_url"));
group.setDescription(rs.getString("description"));
result.add(group);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}
@@ -0,0 +1,135 @@
package org.to.telegramfinalproject.Database;
import org.to.telegramfinalproject.Models.Message;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MessageDatabase {
public void markMessageAsRead(UUID messageId, UUID userId) {
String sql = "INSERT INTO message_receipts (message_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, messageId);
stmt.setObject(2, userId);
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static List<Message> getUnreadMessages(UUID userId) {
List<Message> messages = new ArrayList<>();
String sql = """
SELECT m.* FROM messages m
LEFT JOIN message_receipts r ON m.message_id = r.message_id AND r.user_id = ?
WHERE r.user_id IS NULL
AND (
(m.receiver_type = 'private' AND m.receiver_id = ?)
OR
(m.receiver_type = 'group' AND EXISTS (
SELECT 1 FROM group_members gm WHERE gm.group_id = m.receiver_id AND gm.user_id = ?
))
OR
(m.receiver_type = 'channel' AND EXISTS (
SELECT 1 FROM channel_subscribers cs WHERE cs.channel_id = m.receiver_id AND cs.user_id = ?
))
)
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, userId);
stmt.setObject(2, userId);
stmt.setObject(3, userId);
stmt.setObject(4, userId);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
messages.add(new Message(
UUID.fromString(rs.getString("message_id")),
rs.getObject("sender_id") != null ? UUID.fromString(rs.getString("sender_id")) : null,
rs.getString("receiver_type"),
UUID.fromString(rs.getString("receiver_id")),
rs.getString("content"),
rs.getString("message_type"),
rs.getString("file_url"),
rs.getTimestamp("send_at").toLocalDateTime(),
rs.getString("status"),
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
rs.getBoolean("is_edited"),
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null
));
}
} catch (SQLException e) {
e.printStackTrace();
}
return messages;
}
public static LocalDateTime getLastMessageTimeBetween(UUID user1, UUID user2, String type) {
String sql = """
SELECT MAX(send_at) FROM messages
WHERE receiver_type = ?
AND (
(sender_id = ? AND receiver_id = ?)
OR (sender_id = ? AND receiver_id = ?)
)
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, type);
stmt.setObject(2, user1);
stmt.setObject(3, user2);
stmt.setObject(4, user2);
stmt.setObject(5, user1);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
Timestamp ts = rs.getTimestamp(1);
return ts != null ? ts.toLocalDateTime() : null;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static LocalDateTime getLastMessageTime(UUID receiverId, String type) {
String sql = "SELECT MAX(send_at) FROM messages WHERE receiver_id = ? AND receiver_type = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, receiverId);
stmt.setString(2, type);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
Timestamp ts = rs.getTimestamp(1);
return ts != null ? ts.toLocalDateTime() : null;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,286 @@
package org.to.telegramfinalproject.Database;
import org.to.telegramfinalproject.Models.User;
import java.sql.*;
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<User> getAll() {
List<User> 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;
}
}
public static void updateUserStatus(UUID uuid, String status) {
String sql = "UPDATE users SET status = ? WHERE internal_uuid = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, status);
stmt.setObject(2, uuid);
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void updateLastSeen(UUID uuid) {
String sql = "UPDATE users SET last_seen = CURRENT_TIMESTAMP WHERE internal_uuid = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, uuid);
stmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static User findByInternalUUID(UUID internalUuid) {
String sql = "SELECT * FROM users WHERE internal_uuid = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, internalUuid);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
User user = new User(
rs.getString("user_id"),
UUID.fromString(rs.getString("internal_uuid")),
rs.getString("username"),
rs.getString("password"),
rs.getString("profile_name")
);
user.setBio(rs.getString("bio"));
user.setImage_url(rs.getString("image_url"));
user.setStatus(rs.getString("status"));
Timestamp lastSeenTs = rs.getTimestamp("last_seen");
if (lastSeenTs != null) {
user.setLast_seen(lastSeenTs.toLocalDateTime());
}
return user;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<User> searchUsers(String keyword) {
String query = "SELECT * FROM users WHERE user_id ILIKE ? OR profile_name ILIKE ?"; //(ILIKE) case_insensitive
List<User> result = new ArrayList<>();
try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setString(1, "%" + keyword + "%");
stmt.setString(2, "%" + keyword + "%");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractUser(rs));
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}
@@ -0,0 +1,49 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
public class Channel {
private UUID internal_uuid;
private String channel_id;
private String channel_name;
private UUID creator_id;
private String image_url;
private String description;
private LocalDateTime created_at;
private List<ChannelSubscribe> members;
public Channel(UUID internal_uuid, String channel_name, UUID creator_id, LocalDateTime created_at){
this.internal_uuid = internal_uuid;
this.channel_name = channel_name;
this.creator_id = creator_id;
this.created_at = created_at;
}
public Channel() {
}
public void setChannel_id(String Channel_id){this.channel_id = Channel_id;}
public void setCreator_id(UUID creator_id){this.creator_id = creator_id;}
public void setChannel_name(String channel_name){this.channel_name = channel_name;}
public void setImage_url(String image_url){this.image_url = image_url;}
public void setCreated_at(LocalDateTime created_at){this.created_at = created_at;}
public void setDescription(String description){this.description =description;}
public void setMembers(List<ChannelSubscribe> members){this.members = members;}
public String getChannel_id(){return this.channel_id;}
public UUID getCreator_id(){return this.creator_id;}
public String getChannel_name(){return this.channel_name;}
public String getImage_url(){return this.image_url;}
public LocalDateTime getCreated_at(){return this.created_at;}
public String getDescription(){return this.description;}
public List<ChannelSubscribe> getMembers(){return this.members;}
public UUID getInternal_uuid() {
return this.internal_uuid;
}
public void setInternal_uuid(UUID internalUuid) { this.internal_uuid = internalUuid;
}
}
@@ -0,0 +1,29 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
import java.util.UUID;
public class ChannelSubscribe{
private UUID channel_id;
private UUID user_id;
private LocalDateTime Subscribed_at;
public ChannelSubscribe(UUID channel_id, UUID user_id, String role){
this.channel_id = channel_id;
this.user_id = user_id;
this.Subscribed_at = LocalDateTime.now();
}
public void setChannel_id(UUID group_id){this.channel_id = group_id;}
public void setUser_id(UUID user_id){this.user_id = user_id;}
public void setJoin_at(LocalDateTime join_at){this.Subscribed_at = join_at;}
public UUID getChannel_id(){return this.channel_id;}
public UUID getUser_id(){return this.user_id;}
public LocalDateTime getJoin_at(){return this.Subscribed_at;}
}
@@ -0,0 +1,39 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
public class ChatEntry {
private final String name;
private final String id;
private final String imageUrl;
private final String type; // "private", "group", "channel"
private final LocalDateTime lastMessageTime;
public ChatEntry(String name, String id, String imageUrl, String type, LocalDateTime lastMessageTime) {
this.name = name;
this.id = id;
this.imageUrl = imageUrl;
this.type = type;
this.lastMessageTime = lastMessageTime;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public String getImageUrl() {
return imageUrl;
}
public String getType() {
return type;
}
public LocalDateTime getLastMessageTime() {
return lastMessageTime;
}
}
@@ -0,0 +1,44 @@
package org.to.telegramfinalproject.Models;
import org.json.JSONArray;
import org.json.JSONObject;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
public class Contact {
private UUID user_id;
private UUID contact_id;
private LocalDateTime added_at;
private Boolean is_blocked;
public Contact(UUID user_id, UUID contact_id){
this.user_id = user_id;
this.contact_id = contact_id;
this.added_at = LocalDateTime.now();
}
public void setUser_id(UUID user_id){this.user_id = user_id;}
public void setContact_id(UUID contact_id){this.contact_id = contact_id;}
public void setAdd_at(LocalDateTime add_at){this.added_at =add_at;}
public void setIs_blocked(Boolean is_blocked){this.is_blocked =is_blocked;}
public UUID getUser_id(){
return this.user_id;
}
public UUID getContact_id(){return this.contact_id;}
public LocalDateTime getAdd_at() {
return added_at;
}
public Boolean getIs_blocked(){
return is_blocked;
}
}
@@ -0,0 +1,49 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
public class Group {
private UUID internal_uuid;
private String group_id;
private String group_name;
private UUID creator_id;
private String image_url;
private String description;
private LocalDateTime created_at;
private List<GroupMember> members;
public Group(UUID internal_uuid, String group_name, UUID creator_id, LocalDateTime created_at){
this.internal_uuid = internal_uuid;
this.group_name = group_name;
this.creator_id = creator_id;
this.created_at = created_at;
}
public Group() {
}
public void setGroup_id(String group_id){this.group_id = group_id;}
public void setCreator_id(UUID creator_id){this.creator_id = creator_id;}
public void setGroup_name(String group_name){this.group_name = group_name;}
public void setImage_url(String image_url){this.image_url = image_url;}
public void setCreated_at(LocalDateTime created_at){this.created_at = created_at;}
public void setDescription(String description){this.description =description;}
public void setMembers(List<GroupMember> members){this.members = members;}
public String getGroup_id(){return this.group_id;}
public UUID getCreator_id(){return this.creator_id;}
public String getGroup_name(){return this.group_name;}
public String getImage_url(){return this.image_url;}
public LocalDateTime getCreated_at(){return this.created_at;}
public String getDescription(){return this.description;}
public List<GroupMember> getMembers(){return this.members;}
public UUID getInternal_uuid() {
return this.internal_uuid;
}
public void setInternal_uuid(UUID internalUuid) { this.internal_uuid = internalUuid;
}
}
@@ -0,0 +1,32 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
import java.util.UUID;
public class GroupMember {
private UUID group_id;
private UUID user_id;
private LocalDateTime join_at;
private String role;
public GroupMember(UUID group_id, UUID user_id, String role){
this.group_id = group_id;
this.user_id = user_id;
this.join_at = LocalDateTime.now();
this.role = role;
}
public void setGroup_id(UUID group_id){this.group_id = group_id;}
public void setUser_id(UUID user_id){this.user_id = user_id;}
public void setJoin_at(LocalDateTime join_at){this.join_at = join_at;}
public void setRole(String role){this.role = role;}
public UUID getGroup_id(){return this.group_id;}
public UUID getUser_id(){return this.user_id;}
public LocalDateTime getJoin_at(){return this.join_at;}
public String getRole(){return this.role;}
}
@@ -0,0 +1,157 @@
package org.to.telegramfinalproject.Models;
import org.json.JSONArray;
import org.json.JSONObject;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
public class JsonUtil {
public static JSONArray contactListToJson(List<Contact> contacts) {
JSONArray array = new JSONArray();
for (Contact contact : contacts) {
JSONObject obj = new JSONObject();
obj.put("user_id", contact.getUser_id().toString());
obj.put("contact_id", contact.getContact_id().toString());
obj.put("is_blocked", contact.getIs_blocked());
obj.put("added_at", contact.getAdd_at().toString());
array.put(obj);
}
return array;
}
public static JSONObject userToJson(User user) {
JSONObject obj = new JSONObject();
obj.put("internalUUID", user.getInternal_uuid().toString());
obj.put("user_id", user.getUser_id() != null ?user.getUser_id().toString() :JSONObject.NULL);
obj.put("username", user.getUsername());
obj.put("profile_name", user.getProfile_name());
obj.put("bio", user.getBio()!= null ?user.getBio().toString() :JSONObject.NULL);
obj.put("image_url", user.getImage_url() != null ?user.getImage_url().toString() :JSONObject.NULL);
obj.put("status", user.getStatus());
obj.put("last_seen", user.getLast_seen() != null ? user.getLast_seen().toString() : JSONObject.NULL);
obj.put("contactList", JsonUtil.contactListToJson(user.getContactList()));
obj.put("channelList", JsonUtil.channelListToJson(user.getChannelList()));
obj.put("groupList", JsonUtil.groupListToJson(user.getGroupList()));
obj.put("unreadMessages", JsonUtil.messageListToJson(user.getUnreadMessages()));
return obj;
}
public static JSONArray messageListToJson(List<Message> messages) {
JSONArray array = new JSONArray();
for (Message message : messages) {
JSONObject obj = new JSONObject();
obj.put("message_id", message.getMessage_id().toString());
obj.put("sender_id", message.getSender_id() != null ? message.getSender_id().toString() : JSONObject.NULL);
obj.put("receiver_type", message.getReceiver_type());
obj.put("receiver_id", message.getReceiver_id().toString());
obj.put("content", message.getContent());
obj.put("message_type", message.getMessage_type());
obj.put("file_url", message.getFile_url());
obj.put("send_at", message.getSend_at().toString());
obj.put("status", message.getStatus());
obj.put("reply_to_id", message.getReply_to_id() != null ? message.getReply_to_id().toString() : JSONObject.NULL);
obj.put("is_edited", message.isIs_edited());
obj.put("original_message_id", message.getOriginal_message_id() != null ? message.getOriginal_message_id().toString() : JSONObject.NULL);
obj.put("forwarded_by", message.getForwarded_by() != null ? message.getForwarded_by().toString() : JSONObject.NULL);
obj.put("forwarded_from", message.getForwarded_from() != null ? message.getForwarded_from().toString() : JSONObject.NULL);
array.put(obj);
}
return array;
}
public static JSONArray groupListToJson(List<Group> groups) {
JSONArray array = new JSONArray();
for (Group group : groups) {
JSONObject obj = new JSONObject();
obj.put("internal_uuid", group.getInternal_uuid().toString());
obj.put("group_id", group.getGroup_id() != null ?group.getGroup_id().toString() :JSONObject.NULL);
obj.put("group_name", group.getGroup_name());
obj.put("creator_id", group.getCreator_id().toString());
obj.put("image_url",group.getImage_url()!= null ?group.getImage_url().toString() : JSONObject.NULL );
obj.put("description", group.getDescription() != null ?group.getDescription().toString() : JSONObject.NULL );
obj.put("created_at", group.getCreated_at().toString());
obj.put("members", JsonUtil.groupMemberListToJson(group.getMembers()));
array.put(obj);
}
return array;
}
public static JSONArray channelListToJson(List<Channel> channels) {
JSONArray array = new JSONArray();
for (Channel channel : channels) {
JSONObject obj = new JSONObject();
obj.put("internal_uuid",channel.getInternal_uuid().toString());
obj.put("channel_id", channel.getChannel_id() != null ?channel.getChannel_id().toString() :JSONObject.NULL);
obj.put("channel_name", channel.getChannel_name());
obj.put("creator_id", channel.getCreator_id().toString());
obj.put("image_url",channel.getImage_url()!= null ?channel.getImage_url().toString() : JSONObject.NULL );
obj.put("description",channel.getDescription() != null ?channel.getDescription().toString() : JSONObject.NULL );
obj.put("created_at",channel.getCreated_at().toString());
obj.put("members", JsonUtil.channelSubscribeToJson(channel.getMembers()));
array.put(obj);
}
return array;
}
public static JSONArray groupMemberListToJson(List<GroupMember> members) {
JSONArray array = new JSONArray();
for (GroupMember m : members) {
JSONObject obj = new JSONObject();
obj.put("group_id", m.getGroup_id().toString());
obj.put("user_id", m.getUser_id().toString());
obj.put("joined_at", m.getJoin_at().toString());
obj.put("role", m.getRole());
array.put(obj);
}
return array;
}
public static JSONArray channelSubscribeToJson(List<ChannelSubscribe> subscribes){
JSONArray array = new JSONArray();
for(ChannelSubscribe s :subscribes ){
JSONObject obj = new JSONObject();
obj.put("channel_id",s.getChannel_id().toString());
obj.put("user_id", s.getUser_id().toString());
obj.put("Subscribed_at", s.getJoin_at().toString());
}
return array;
}
public static JSONArray chatListToJson(List<ChatEntry> chatList) {
JSONArray jsonArray = new JSONArray();
for (ChatEntry entry : chatList) {
JSONObject obj = new JSONObject();
obj.put("id", entry.getId() != null ?entry.getId() :JSONObject.NULL);
obj.put("name", entry.getName());
obj.put("image_url", entry.getImageUrl() != null ?entry.getImageUrl() :JSONObject.NULL);
obj.put("type", entry.getType());
obj.put("last_message_time", entry.getLastMessageTime() != null ? entry.getLastMessageTime().toString() : JSONObject.NULL);
jsonArray.put(obj);
}
return jsonArray;
}
}
@@ -0,0 +1,32 @@
package org.to.telegramfinalproject.Models;
import java.util.List;
public class LoginBootstrapData {
private User user;
private List<Contact> contacts;
private List<Group> groups;
private List<Channel> channels;
private List<Message> unreadMessages;
public LoginBootstrapData(User user, List<Contact> contacts, List<Group> groups,
List<Channel> channels, List<Message> unreadMessages) {
this.user = user;
this.contacts = contacts;
this.groups = groups;
this.channels = channels;
this.unreadMessages = unreadMessages;
}
public void setUnreadMessages(List<Message> unreadMessages){this.unreadMessages = unreadMessages;}
public void setContacts(List<Contact> contacts){this.contacts =contacts;}
public void setGroups(List<Group> groups){this.groups = groups;}
public void setChannels(List<Channel> channels){this.channels = channels;}
public void setUser(User user){this.user = user;}
public List<Message> getUnreadMessages(){return unreadMessages;}
public List<Group> getGroups(){return groups;}
public List<Contact> getContacts(){return contacts;}
public List<Channel> getChannels(){return channels;}
public User getUser(User user){return user;}
}
@@ -0,0 +1,151 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
import java.util.UUID;
public class Message {
private UUID message_id;
private UUID sender_id;
private String receiver_type; // private, group, channel
private UUID receiver_id;
private String content;
private String message_type; // TEXT, IMAGE, FILE, ...
private String file_url;
private LocalDateTime send_at;
private String status; // SENT, DELIVERED, READ
private UUID reply_to_id;
private boolean is_edited;
private UUID original_message_id;
private UUID forwarded_by;
private UUID forwarded_from;
public Message(UUID message_id, UUID sender_id, String receiver_type, UUID receiver_id, String content,
String message_type, String file_url, LocalDateTime send_at, String status,
UUID reply_to_id, boolean is_edited, UUID original_message_id,
UUID forwarded_by, UUID forwarded_from) {
this.message_id = message_id;
this.sender_id = sender_id;
this.receiver_type = receiver_type;
this.receiver_id = receiver_id;
this.content = content;
this.message_type = message_type;
this.file_url = file_url;
this.send_at = send_at;
this.status = status;
this.reply_to_id = reply_to_id;
this.is_edited = is_edited;
this.original_message_id = original_message_id;
this.forwarded_by = forwarded_by;
this.forwarded_from = forwarded_from;
}
public UUID getMessage_id() {
return message_id;
}
public UUID getSender_id() {
return sender_id;
}
public void setSender_id(UUID sender_id) {
this.sender_id = sender_id;
}
public String getReceiver_type() {
return receiver_type;
}
public void setReceiver_type(String receiver_type) {
this.receiver_type = receiver_type;
}
public UUID getReceiver_id() {
return receiver_id;
}
public void setReceiver_id(UUID receiver_id) {
this.receiver_id = receiver_id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getMessage_type() {
return message_type;
}
public void setMessage_type(String message_type) {
this.message_type = message_type;
}
public String getFile_url() {
return file_url;
}
public void setFile_url(String file_url) {
this.file_url = file_url;
}
public LocalDateTime getSend_at() {
return send_at;
}
public void setSend_at(LocalDateTime send_at) {
this.send_at = send_at;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public UUID getReply_to_id() {
return reply_to_id;
}
public void setReply_to_id(UUID reply_to_id) {
this.reply_to_id = reply_to_id;
}
public boolean isIs_edited() {
return is_edited;
}
public void setIs_edited(boolean is_edited) {
this.is_edited = is_edited;
}
public UUID getOriginal_message_id() {
return original_message_id;
}
public void setOriginal_message_id(UUID original_message_id) {
this.original_message_id = original_message_id;
}
public UUID getForwarded_by() {
return forwarded_by;
}
public void setForwarded_by(UUID forwarded_by) {
this.forwarded_by = forwarded_by;
}
public UUID getForwarded_from() {
return forwarded_from;
}
public void setForwarded_from(UUID forwarded_from) {
this.forwarded_from = forwarded_from;
}
}
@@ -0,0 +1,30 @@
package org.to.telegramfinalproject.Models;
import java.time.LocalDateTime;
import java.util.UUID;
public class PrivateChat {
private UUID chat_id;
private UUID user1_id;
private UUID user2_id;
private LocalDateTime created_at;
public PrivateChat(UUID chat_id, UUID user1_id, UUID user2_id, LocalDateTime created_at){
this.chat_id = chat_id;
this.user1_id =user1_id;
this.user2_id =user2_id;
this.created_at =created_at;
}
public void setUser1_id(UUID user1_id){this.user1_id =user1_id;}
public void setUser2_id(UUID user2_id){this.user2_id =user2_id;}
public void setCreated_at(LocalDateTime created_at){this.created_at = created_at;}
public UUID getUser1_id(){return this.user1_id;}
public UUID getChat_id(){return this.chat_id;}
public UUID getUser2_id(){return this.user2_id;}
public LocalDateTime getCreated_at(){return this.created_at;}
}
@@ -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;
}
}
@@ -0,0 +1,32 @@
package org.to.telegramfinalproject.Models;
import org.json.JSONObject;
public class ResponseModel {
private String status;
private String message;
private JSONObject data;
public ResponseModel(String status, String message) {
this.status = status;
this.message = message;
this.data = null;
}
public ResponseModel(String status, String message, JSONObject data) {
this.status = status;
this.message = message;
this.data = data;
}
public String getStatus() {
return this.status;
}
public String getMessage() {
return this.message;
}
public JSONObject getData() {return this.data;}
}
@@ -0,0 +1,19 @@
package org.to.telegramfinalproject.Models;
public class SearchRequestModel {
private String action;
private String keyword;
public SearchRequestModel(String action, String keyword) {
this.action = action;
this.keyword = keyword;
}
public String getAction() {
return action;
}
public String getKeyword() {
return keyword;
}
}
@@ -0,0 +1,125 @@
package org.to.telegramfinalproject.Models;
import org.json.JSONObject;
import java.time.LocalDateTime;
import java.util.List;
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;
private List<Contact> contactList;
private List<Group> groupList;
private List<Channel> channelList;
private List<Message> unreadMessages;
private List<ChatEntry> chatList;
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 void setContactList(List<Contact> contactList){this.contactList = contactList;}
public void setChannelList(List<Channel> channelList){this.channelList = channelList;}
public void setGroupList(List<Group> groupList){this.groupList = groupList;}
public void setUnreadMessages(List<Message> unreadMessages){this.unreadMessages = unreadMessages;}
public void setChatList(List<ChatEntry> chatList){this.chatList = chatList;}
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;
}
public List<Contact> getContactList(){return this.contactList;}
public List<Channel> getChannelList(){return this.channelList;}
public List<Group> getGroupList(){return this.groupList;}
public List<Message> getUnreadMessages(){return this.unreadMessages;}
public List<ChatEntry> getChatList(){return this.chatList;}
}
@@ -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);
}
}
@@ -0,0 +1,59 @@
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;
}
}
public boolean loginCheck(String username , String password){
User user = userDb.findByUsername(username);
String pass = user.getPassword();
password = PasswordHashing.hash(password);
String Username = user.getUsername();
boolean login = false;
if(user!= null && Username.equals(username)&& pass.equals(password)){
login = true;
}
return login;
}
}
@@ -0,0 +1,182 @@
package org.to.telegramfinalproject.Server;
import org.json.JSONArray;
import org.json.JSONObject;
import org.to.telegramfinalproject.Database.*;
import org.to.telegramfinalproject.Models.*;
import java.io.*;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.*;
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);
String action = requestJson.getString("action");
ResponseModel response = null;
System.out.println("Received action: '" + action + "'");
System.out.println("Full request: " + requestJson.toString());
if (!requestJson.has("action") || requestJson.isNull("action")) {
ResponseModel errorResponse = new ResponseModel("error", "Missing 'action' in request.");
JSONObject responseJson = new JSONObject();
responseJson.put("status", errorResponse.getStatus());
responseJson.put("message", errorResponse.getMessage());
responseJson.put("data", JSONObject.NULL);
out.println(responseJson.toString());
continue;
}
switch (action) {
case "register":
case "login": {
RequestModel request = new RequestModel(
action,
requestJson.optString("user_id"),
requestJson.optString("username"),
requestJson.optString("password"),
requestJson.optString("profile_name")
);
if (action.equals("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.");
} else {
User user = authService.login(request.getUsername(), request.getPassword());
if (user == null) {
response = new ResponseModel("error", "Login failed.");
break;
}
SessionManager.addUser(user.getInternal_uuid(), this.socket);
userDatabase.updateUserStatus(user.getInternal_uuid(), "online");
List<Contact> contacts = ContactDatabase.getContacts(user.getInternal_uuid());
List<Group> groups = GroupDatabase.getGroupsByUser(user.getInternal_uuid());
List<Channel> channels = ChannelDatabase.getChannelsByUser(user.getInternal_uuid());
List<Message> unreadMessages = MessageDatabase.getUnreadMessages(user.getInternal_uuid());
user.setContactList(contacts);
user.setGroupList(groups);
user.setChannelList(channels);
user.setUnreadMessages(unreadMessages);
List<ChatEntry> chatList = new ArrayList<>();
for (Contact contact : contacts) {
User target = userDatabase.findByInternalUUID(contact.getContact_id());
if (target == null) continue;
LocalDateTime last = MessageDatabase.getLastMessageTimeBetween(user.getInternal_uuid(), target.getInternal_uuid(), "private");
chatList.add(new ChatEntry(target.getUser_id(), target.getProfile_name(), target.getImage_url(), "private", last));
}
for (Group group : groups) {
LocalDateTime last = MessageDatabase.getLastMessageTime(group.getInternal_uuid(), "group");
chatList.add(new ChatEntry(group.getGroup_id(), group.getGroup_name(), group.getImage_url(), "group", last));
}
for (Channel channel : channels) {
LocalDateTime last = MessageDatabase.getLastMessageTime(channel.getInternal_uuid(), "channel");
chatList.add(new ChatEntry(channel.getChannel_id(), channel.getChannel_name(), channel.getImage_url(), "channel", last));
}
chatList.sort((a, b) -> {
if (a.getLastMessageTime() == null) return 1;
if (b.getLastMessageTime() == null) return -1;
return b.getLastMessageTime().compareTo(a.getLastMessageTime());
});
JSONObject userData = JsonUtil.userToJson(user);
userData.put("chat_list", JsonUtil.chatListToJson(chatList));
response = new ResponseModel("success", "Welcome " + user.getProfile_name(), userData);
}
break;
}
case "logout": {
String userId = requestJson.optString("user_id");
if (userId != null && !userId.isEmpty()) {
UUID uuid = UUID.fromString(userId);
userDatabase.updateUserStatus(uuid, "offline");
userDatabase.updateLastSeen(uuid);
SessionManager.removeUser(uuid);
response = new ResponseModel("success", "Logged out.");
} else {
response = new ResponseModel("error", "Invalid user_id for logout.");
}
break;
}
case "search": {
String keyword = requestJson.optString("keyword");
List<JSONObject> results = new ArrayList<>();
for (User u : new userDatabase().searchUsers(keyword)) {
JSONObject obj = new JSONObject();
obj.put("type", "user");
obj.put("id", u.getUser_id());
obj.put("name", u.getProfile_name());
results.add(obj);
}
for (Group g : GroupDatabase.searchGroups(keyword)) {
JSONObject obj = new JSONObject();
obj.put("type", "group");
obj.put("id", g.getGroup_id());
obj.put("name", g.getGroup_name());
results.add(obj);
}
for (Channel c : ChannelDatabase.searchChannels(keyword)) {
JSONObject obj = new JSONObject();
obj.put("type", "channel");
obj.put("id", c.getChannel_id());
obj.put("name", c.getChannel_name());
results.add(obj);
}
JSONObject data = new JSONObject();
data.put("results", new JSONArray(results));
response = new ResponseModel("success", "Search results found", data);
break;
}
default:
response = new ResponseModel("error", "Unknown action: " + action);
}
JSONObject responseJson = new JSONObject();
responseJson.put("status", response.getStatus());
responseJson.put("message", response.getMessage());
responseJson.put("data", response.getData() != null ? response.getData() : JSONObject.NULL);
out.println(responseJson.toString());
}
} catch (IOException e) {
System.out.println("Connection with client lost.");
UUID userId = SessionManager.getUserIdBySocket(this.socket);
if (userId != null) {
userDatabase.updateUserStatus(userId, "offline");
userDatabase.updateLastSeen(userId);
SessionManager.removeUser(userId);
}
}
}
}
@@ -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();
}
}
}
@@ -0,0 +1,35 @@
package org.to.telegramfinalproject.Server;
import java.net.Socket;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class SessionManager {
private static final Map<UUID, Socket> onlineUsers = new ConcurrentHashMap<>(); //catch UUID for find the user socket
public static void addUser(UUID userId, Socket socket) {
onlineUsers.put(userId, socket);
}
public static void removeUser(UUID userId) {
onlineUsers.remove(userId);
}
public static boolean isOnline(UUID userId) {
return onlineUsers.containsKey(userId);
}
public static Socket getUserSocket(UUID userId) {
return onlineUsers.get(userId);
}
public static UUID getUserIdBySocket(Socket socket) {
for (Map.Entry<UUID, Socket> entry : onlineUsers.entrySet()) {
if (entry.getValue().equals(socket)) {
return entry.getKey();
}
}
return null;
}
}
@@ -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();
}
}
}
@@ -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();
}
}
}
@@ -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();
}
}
@@ -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();
}
}
}
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="709.0" prefWidth="600.0" style="-fx-background-color: linear-gradient(to right, #B39DDB, #81D4FA); -fx-background-radius: 12;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.to.telegramfinalproject.UI.LoginForm">
<children>
<TextField fx:id="usernameField" layoutX="289.0" layoutY="189.0" />
<PasswordField fx:id="passwordField" layoutX="289.0" layoutY="297.0" />
<Label layoutX="258.0" layoutY="69.0" text="Login" textAlignment="CENTER" textFill="WHITE">
<font>
<Font name="System Bold" size="40.0" />
</font>
</Label>
<Label layoutX="89.0" layoutY="182.0" text="Username :" textAlignment="CENTER" textFill="WHITE">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<Label layoutX="88.0" layoutY="290.0" text="Password :" textFill="WHITE">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<Button fx:id="loginButton" layoutX="225.0" layoutY="449.0" mnemonicParsing="false" prefHeight="39.0" prefWidth="176.0" style="-fx-background-color: #f8bbd0; -fx-border-radius: 12; -fx-border-color: #6a1b9a; -fx-background-radius: 12;" text="Login" textFill="#79195c">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Button>
<Button fx:id="backButton" layoutX="227.0" layoutY="532.0" mnemonicParsing="false" prefHeight="39.0" prefWidth="176.0" style="-fx-background-color: #f8bbd0; -fx-background-radius: 12; -fx-border-color: #6a1b9a; -fx-border-radius: 12;" text="Back" textFill="#79195c">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Button>
</children>
</AnchorPane>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="709.0" prefWidth="600.0" style="-fx-background-color: linear-gradient(to right, #B39DDB, #81D4FA);" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.to.telegramfinalproject.UI.RegisterForm">
<children>
<Label layoutX="223.0" layoutY="56.0" text="Register" textAlignment="CENTER" textFill="#fffefe">
<font>
<Font name="System Bold" size="40.0" />
</font>
</Label>
<Label layoutX="52.0" layoutY="160.0" text="User ID:" textFill="#f5f5f5">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<Label layoutX="52.0" layoutY="249.0" text="Username:" textAlignment="CENTER" textFill="#f5efef">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<Label layoutX="52.0" layoutY="348.0" text="Profile name:" textAlignment="CENTER" textFill="#f5f5f5">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<Label layoutX="46.0" layoutY="442.0" text="Password:" textAlignment="CENTER" textFill="#fffafa">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<Label layoutX="27.0" layoutY="535.0" text="Check password:" textFill="WHITE">
<font>
<Font name="System Italic" size="36.0" />
</font>
</Label>
<TextField fx:id="userIdField" layoutX="294.0" layoutY="167.0" />
<TextField fx:id="usernameField" layoutX="294.0" layoutY="256.0" />
<TextField fx:id="profileNameField" layoutX="294.0" layoutY="355.0" />
<PasswordField fx:id="passwordField" layoutX="294.0" layoutY="449.0" />
<PasswordField fx:id="confirmPasswordField" layoutX="294.0" layoutY="542.0" />
<Button fx:id="submitButton" layoutX="367.0" layoutY="626.0" mnemonicParsing="false" style="-fx-background-color: #f8bbd0; -fx-background-radius: 12; -fx-border-color: #6a1b9a; -fx-border-radius: 12;" text="Submit" textAlignment="CENTER" textFill="#79195c">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Button>
<Button fx:id="backButton" layoutX="146.0" layoutY="626.0" mnemonicParsing="false" prefHeight="41.0" prefWidth="87.0" style="-fx-background-color: #f8bbd0; -fx-background-radius: 12; -fx-border-color: #6a1b9a; -fx-border-radius: 12;" text="Back" textFill="#79195c" />
</children>
</AnchorPane>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane prefHeight="600.0" prefWidth="800.0" style="-fx-background-color: #f5f5f5;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.to.telegramfinalproject.UI.login_view">
<children>
<VBox alignment="CENTER">
<children>
<AnchorPane prefHeight="596.0" prefWidth="800.0" style="-fx-background-color: linear-gradient(to right, #B39DDB, #81D4FA); -fx-background-radius: 15;">
<children>
<Label layoutX="448.0" layoutY="55.0" text="Telegarm" textAlignment="CENTER" textFill="#ffffff">
<font>
<Font name="System Bold" size="40.0" />
</font>
</Label>
<Button fx:id="loginButton" layoutX="462.0" layoutY="170.0" prefHeight="50.0" prefWidth="150.0" style="-fx-background-color: #f8bbd0; -fx-text-fill: #6a1b9a; -fx-background-radius: 12; -fx-font-weight: bold;" text="Login" />
<Button fx:id="registerButton" layoutX="462.0" layoutY="267.0" prefHeight="50.0" prefWidth="150.0" style="-fx-background-color: #f8bbd0; -fx-text-fill: #6a1b9a; -fx-background-radius: 12; -fx-font-weight: bold;" text="Register" />
</children>
</AnchorPane>
</children>
</VBox>
</children>
</StackPane>