Valentin Spiroski
11 months ago
11 changed files with 667 additions and 0 deletions
-
4.gitignore
-
18pom.xml
-
112src/main/java/ChatClient.java
-
60src/main/java/ChatServer.java
-
65src/main/java/ClientHandler.java
-
5src/main/java/Constants.java
-
155src/main/java/CreateUser.java
-
122src/main/java/LoginGUI.java
-
103src/main/java/SignUpGUI.java
-
0src/main/java/test
-
23user.json
@ -0,0 +1,4 @@ |
|||
/target/ |
|||
/.idea/ |
|||
/.settings/ |
|||
java-chat.iml |
@ -0,0 +1,112 @@ |
|||
import javax.swing.*; |
|||
import java.awt.*; |
|||
import java.awt.event.KeyEvent; |
|||
import java.awt.event.KeyListener; |
|||
import java.io.*; |
|||
import java.net.Socket; |
|||
|
|||
public class ChatClient extends JFrame implements KeyListener { |
|||
private String address; |
|||
private String connectionFailedMessage; |
|||
private Socket connectionToServer; |
|||
private BufferedReader fromServerReader; |
|||
private PrintWriter toServerWriter; |
|||
|
|||
// GUI |
|||
private JTextArea outputTextArea; |
|||
private JTextField inputTextField; |
|||
private JScrollPane outputScrollPane; |
|||
|
|||
public ChatClient() { |
|||
super("Chat"); |
|||
address = JOptionPane.showInputDialog("bitte IP-Adresse"); |
|||
if (null != address) { |
|||
connectionFailedMessage = "Verbindung zum Server " + (address.isEmpty() ? "" : ("\"" + address + "\"")) + " fehlgeschlagen."; |
|||
receiveMessages(); |
|||
} |
|||
} |
|||
|
|||
private void initGui() { |
|||
outputTextArea = new JTextArea(); |
|||
outputTextArea.setEditable(false); |
|||
outputTextArea.setBorder(BorderFactory.createTitledBorder("Chat")); |
|||
|
|||
outputScrollPane = new JScrollPane(outputTextArea); |
|||
|
|||
inputTextField = new JTextField(); |
|||
inputTextField.setBorder(BorderFactory.createTitledBorder("Nachricht eingeben")); |
|||
inputTextField.addKeyListener(this); |
|||
|
|||
add(outputScrollPane, BorderLayout.CENTER); |
|||
add(inputTextField, BorderLayout.SOUTH); |
|||
|
|||
setVisible(true); |
|||
setSize(Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT); |
|||
setDefaultCloseOperation(EXIT_ON_CLOSE); |
|||
setLocationRelativeTo(null); |
|||
} |
|||
private void receiveMessages() { |
|||
try { |
|||
connectionToServer = new Socket(address, Constants.PORT); |
|||
fromServerReader = new BufferedReader(new InputStreamReader(connectionToServer.getInputStream())); |
|||
toServerWriter = new PrintWriter(new OutputStreamWriter(connectionToServer.getOutputStream())); |
|||
|
|||
initGui(); |
|||
|
|||
while (true) { |
|||
String message = fromServerReader.readLine(); |
|||
outputTextArea.append(message + "\n"); |
|||
outputScrollPane.getVerticalScrollBar().setValue(outputScrollPane.getVerticalScrollBar().getMaximum()); |
|||
} |
|||
} catch (IOException e) { |
|||
JOptionPane.showMessageDialog(null, connectionFailedMessage); |
|||
dispose(); |
|||
} finally { |
|||
if (null != connectionToServer) { |
|||
try { |
|||
connectionToServer.close(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
if (null != fromServerReader) { |
|||
try { |
|||
fromServerReader.close(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
if(null != toServerWriter) { |
|||
toServerWriter.close(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void keyTyped(KeyEvent e) { |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void keyPressed(KeyEvent e) { |
|||
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
|||
String message = inputTextField.getText(); |
|||
if (!message.isEmpty()) { |
|||
toServerWriter.println(message); |
|||
toServerWriter.flush(); |
|||
inputTextField.setText(""); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void keyReleased(KeyEvent e) { |
|||
|
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
new ChatClient(); |
|||
} |
|||
} |
@ -0,0 +1,60 @@ |
|||
|
|||
import java.io.IOException; |
|||
import java.net.ServerSocket; |
|||
import java.net.Socket; |
|||
import java.util.List; |
|||
import java.util.concurrent.CopyOnWriteArrayList; |
|||
|
|||
public class ChatServer { |
|||
private ServerSocket serverSocket; |
|||
private List<ClientHandler> clients; // Liste, um alle verbundenen Clients zu verwalten |
|||
|
|||
public ChatServer(int port) { |
|||
clients = new CopyOnWriteArrayList<>(); // Verwende CopyOnWriteArrayList für die Thread-Sicherheit |
|||
|
|||
try { |
|||
serverSocket = new ServerSocket(port); |
|||
System.out.println("Started ChatServer on port " + port); |
|||
|
|||
while (true) { |
|||
System.out.println("waiting for new Client..."); |
|||
Socket connectionToClient = serverSocket.accept(); // Auf Verbindungen von Clients warten |
|||
ClientHandler client = new ClientHandler(this, connectionToClient); |
|||
clients.add(client); // Neuen Client zur Liste hinzufügen |
|||
System.out.println("Accepted new Client"); |
|||
} |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} finally { |
|||
if (serverSocket != null) { |
|||
try { |
|||
serverSocket.close(); |
|||
} catch (IOException e) { |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
// Methode, um eine Nachricht an alle verbundenen Clients zu senden |
|||
public void broadcastMessage(String message) { |
|||
System.out.println(message); |
|||
if (message != null) { |
|||
for (ClientHandler client : clients) { |
|||
client.sendMessage(message); // Nachricht an jeden Client senden |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
new ChatServer(3141); // ChatServer auf Port 3141 starten (eventuell den Port flexibler noch wählen? falls belegt) |
|||
|
|||
} |
|||
// Methode, um einen Client aus der Liste der verbundenen Clients zu entfernen |
|||
public void removeClient(ClientHandler client) { |
|||
clients.remove(client); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,65 @@ |
|||
import java.io.*; |
|||
import java.net.Socket; |
|||
|
|||
public class ClientHandler implements Runnable { |
|||
private ChatServer chatServer; |
|||
private Socket connectionToClient; |
|||
private String name; |
|||
private BufferedReader fromClientReader; |
|||
private PrintWriter toClientWriter; |
|||
|
|||
// Constructor for ClientHandler |
|||
public ClientHandler(ChatServer chatServer, Socket connectionToClient) { |
|||
this.chatServer = chatServer; |
|||
this.connectionToClient = connectionToClient; |
|||
name = connectionToClient.getInetAddress().getHostAddress(); // Use the client's IP address as their name for simplicity |
|||
|
|||
new Thread(this).start();} // Start a new thread for this client handler |
|||
|
|||
@Override |
|||
public void run() { |
|||
|
|||
try { |
|||
// Set up input and output streams for communication with the client |
|||
fromClientReader = new BufferedReader (new InputStreamReader(connectionToClient.getInputStream())); |
|||
toClientWriter = new PrintWriter (new OutputStreamWriter(connectionToClient.getOutputStream())); |
|||
|
|||
chatServer.broadcastMessage(name + " connected."); // Broadcast a message when the client is connected |
|||
|
|||
// Read messages from the client and broadcast them to all clients |
|||
String message = fromClientReader.readLine(); |
|||
while (message!=null) { |
|||
// Broadcast the client's message to all connected clients |
|||
chatServer.broadcastMessage(name + ": " + message); |
|||
message = fromClientReader.readLine(); |
|||
} |
|||
} |
|||
|
|||
catch (IOException e) { |
|||
throw new RuntimeException(e); // Handle exceptions by throwing a runtime exception |
|||
} |
|||
finally { |
|||
chatServer.removeClient(this); |
|||
chatServer.broadcastMessage(name + " disconnected."); // Broadcast a message when the client is disconnected |
|||
|
|||
// Close resources in the finally block |
|||
if (fromClientReader != null) { |
|||
try { |
|||
fromClientReader.close(); |
|||
} |
|||
catch (IOException e){ |
|||
e.printStackTrace(); |
|||
} |
|||
} |
|||
if (toClientWriter != null) { |
|||
toClientWriter.close(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
//Method to send a message to the client |
|||
public void sendMessage(String message) { |
|||
toClientWriter.println(message); // Send the message to the client |
|||
toClientWriter.flush(); // Flush the stream |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
public class Constants { |
|||
public static final int WINDOW_WIDTH = 800; |
|||
public static final int WINDOW_HEIGHT = 600; |
|||
public static final int PORT = 3141; |
|||
} |
@ -0,0 +1,155 @@ |
|||
import com.google.gson.Gson; |
|||
import com.google.gson.GsonBuilder; |
|||
import com.google.gson.reflect.TypeToken; |
|||
|
|||
import java.io.*; |
|||
import java.lang.reflect.Type; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
import java.io.FileWriter; |
|||
import java.io.IOException; |
|||
|
|||
import java.util.UUID; |
|||
|
|||
class CreateUser { |
|||
private String id; |
|||
private String userName; |
|||
private String password; |
|||
private String birthday; |
|||
private boolean stayLoggedIn; |
|||
|
|||
|
|||
// Constructor |
|||
public CreateUser(String id, String name, String password, String birthday) { |
|||
this.id = id; |
|||
this.userName = name; |
|||
this.password = password; |
|||
this.birthday = birthday; |
|||
} |
|||
|
|||
// Getters and Setters |
|||
public String getId() { |
|||
return id; |
|||
} |
|||
|
|||
public void setId(String id) { |
|||
this.id = id; |
|||
} |
|||
|
|||
public String getUserName() { |
|||
return userName; |
|||
} |
|||
|
|||
public void setUserName(String userName) { |
|||
this.userName = userName; |
|||
} |
|||
|
|||
public String getPassword() { |
|||
return password; |
|||
} |
|||
|
|||
public void setPassword(String password) { |
|||
this.password = password; |
|||
} |
|||
|
|||
public String getBirthday() { |
|||
return birthday; |
|||
} |
|||
|
|||
public void setBirthday(String birthday) { |
|||
this.birthday = birthday; |
|||
} |
|||
|
|||
public boolean isStayLoggedIn() { |
|||
return stayLoggedIn; |
|||
} |
|||
|
|||
public void setStayLoggedIn(boolean stayLoggedIn) { |
|||
this.stayLoggedIn = stayLoggedIn; |
|||
} |
|||
|
|||
// Function to create user with validation |
|||
public static CreateUser createUser(String id, String userName, String password, String birthday) { |
|||
if (userName == null || userName.isEmpty()) { |
|||
throw new IllegalArgumentException("Username cannot be empty"); |
|||
} |
|||
if (password == null || password.isEmpty()) { |
|||
throw new IllegalArgumentException("Password cannot be empty"); |
|||
} |
|||
if (password.length() < 6) { |
|||
throw new IllegalArgumentException("Password must be at least 6 characters long"); |
|||
} return new CreateUser(id, userName, password, birthday); |
|||
} |
|||
|
|||
// Function to save to JSON file, replace with database call later |
|||
public void saveToJsonFile(String filename) { |
|||
List<CreateUser> userList = readUserListFromJsonFile(filename); |
|||
userList.add(this); |
|||
|
|||
try (FileWriter fileWriter = new FileWriter(filename)) { |
|||
Gson gson = new GsonBuilder().setPrettyPrinting().create(); |
|||
gson.toJson(userList, fileWriter); |
|||
System.out.println("User information appended to " + filename); |
|||
} catch (IOException e) { |
|||
System.out.println("Error occurred while saving user information to JSON file: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
// Function to read user information from a JSON file |
|||
public static List<CreateUser> readUserListFromJsonFile(String filename) { |
|||
List<CreateUser> userList = new ArrayList<>(); |
|||
try (Reader reader = new FileReader(filename)) { |
|||
Type userListType = new TypeToken<List<CreateUser>>() {}.getType(); |
|||
Gson gson = new Gson(); |
|||
userList = gson.fromJson(reader, userListType); |
|||
} catch (FileNotFoundException e) { |
|||
// File does not exist yet, so return an empty list |
|||
} catch (IOException e) { |
|||
System.out.println("Error occurred while reading user information from JSON file: " + e.getMessage()); |
|||
} |
|||
return userList; |
|||
} |
|||
|
|||
// Function to update stayLoggedIn variable in the JSON file |
|||
public static void updateStayLoggedIn(String filename, String username, boolean stayLoggedIn) { |
|||
List<CreateUser> userList = readUserListFromJsonFile(filename); |
|||
|
|||
for (CreateUser user : userList) { |
|||
if (user.getUserName().equals(username)) { |
|||
user.setStayLoggedIn(stayLoggedIn); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
try (FileWriter fileWriter = new FileWriter(filename)) { |
|||
Gson gson = new GsonBuilder().setPrettyPrinting().create(); |
|||
gson.toJson(userList, fileWriter); |
|||
System.out.println("StayLoggedIn updated in " + filename); |
|||
} catch (IOException e) { |
|||
System.out.println("Error occurred while updating StayLoggedIn in JSON file: " + e.getMessage()); |
|||
} |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
try { |
|||
// Example usage |
|||
UUID randomUUID = UUID.randomUUID(); |
|||
CreateUser user = createUser(randomUUID.toString(), "Test User", "TestPasswort123", "01.01.2000"); |
|||
|
|||
// Example of accessing properties |
|||
System.out.println("UserID: " + user.getId()); |
|||
System.out.println("User Name: " + user.getUserName()); |
|||
System.out.println("User Password: " + user.getPassword()); |
|||
System.out.println("User Birthday: " + user.getBirthday()); |
|||
|
|||
|
|||
// Save user information to a JSON file |
|||
user.saveToJsonFile("user.json"); |
|||
|
|||
updateStayLoggedIn("user.json", "Test User", true); |
|||
} catch (IllegalArgumentException e) { |
|||
System.out.println("Error: " + e.getMessage()); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,122 @@ |
|||
import javax.swing.*; |
|||
import java.awt.event.ActionEvent; |
|||
import java.awt.event.ActionListener; |
|||
import java.util.List; |
|||
import java.awt.event.KeyEvent; |
|||
import java.awt.event.KeyListener; |
|||
|
|||
public class LoginGUI extends JFrame implements ActionListener { |
|||
private JTextField usernameField; |
|||
private JPasswordField passwordField; |
|||
private JButton loginButton; |
|||
private JCheckBox stayLoggedInCheckbox; |
|||
|
|||
public LoginGUI() { |
|||
setTitle("Login"); |
|||
setSize(300, 180); |
|||
setDefaultCloseOperation(EXIT_ON_CLOSE); |
|||
setLayout(null); |
|||
|
|||
JLabel usernameLabel = new JLabel("Username:"); |
|||
usernameLabel.setBounds(20, 20, 80, 25); |
|||
add(usernameLabel); |
|||
|
|||
usernameField = new JTextField(); |
|||
usernameField.setBounds(100, 20, 160, 25); |
|||
add(usernameField); |
|||
|
|||
JLabel passwordLabel = new JLabel("Password:"); |
|||
passwordLabel.setBounds(20, 50, 80, 25); |
|||
add(passwordLabel); |
|||
|
|||
passwordField = new JPasswordField(); |
|||
passwordField.setBounds(100, 50, 160, 25); |
|||
add(passwordField); |
|||
|
|||
stayLoggedInCheckbox = new JCheckBox("Stay Logged In"); |
|||
stayLoggedInCheckbox.setBounds(20, 80, 150, 25); |
|||
add(stayLoggedInCheckbox); |
|||
|
|||
loginButton = new JButton("Login"); |
|||
loginButton.setBounds(100, 110, 100, 25); |
|||
loginButton.addActionListener(this); |
|||
add(loginButton); |
|||
|
|||
getRootPane().setDefaultButton(loginButton); |
|||
|
|||
passwordField.addKeyListener(new EnterKeyListener()); |
|||
|
|||
stayLoggedInCheckbox.addActionListener(new ActionListener() { |
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
boolean stayLoggedIn = stayLoggedInCheckbox.isSelected(); |
|||
String username = usernameField.getText(); |
|||
updateStayLoggedIn(username, stayLoggedIn); |
|||
} |
|||
}); |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
if (e.getSource() == loginButton) { |
|||
login(); |
|||
} |
|||
} |
|||
|
|||
private void login() { |
|||
String username = usernameField.getText(); |
|||
String password = new String(passwordField.getPassword()); |
|||
boolean stayLoggedIn = stayLoggedInCheckbox.isSelected(); // Get checkbox state |
|||
|
|||
if (authenticateUser(username, password)) { |
|||
JOptionPane.showMessageDialog(this, "Login successful!"); |
|||
// Perform actions after successful login |
|||
|
|||
dispose(); |
|||
} else { |
|||
JOptionPane.showMessageDialog(this, "Invalid username or password", "Login Error", JOptionPane.ERROR_MESSAGE); |
|||
} |
|||
} |
|||
|
|||
private void updateStayLoggedIn(String username, boolean stayLoggedIn) { |
|||
// Update stayLoggedIn in the JSON file for the user |
|||
CreateUser.updateStayLoggedIn("user.json", username, stayLoggedIn); |
|||
} |
|||
|
|||
// Function to authenticate the user by comparing the entered username and password with the saved user data |
|||
private boolean authenticateUser(String username, String password) { |
|||
List<CreateUser> userList = CreateUser.readUserListFromJsonFile("user.json"); |
|||
if (userList != null) { |
|||
for (CreateUser user : userList) { |
|||
if (user.getUserName().equals(username) && user.getPassword().equals(password)) { |
|||
return true; //Success |
|||
} |
|||
} |
|||
} |
|||
return false; // Fail |
|||
} |
|||
|
|||
|
|||
private class EnterKeyListener implements KeyListener { |
|||
@Override |
|||
public void keyTyped(KeyEvent e) {} |
|||
|
|||
@Override |
|||
public void keyPressed(KeyEvent e) { |
|||
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
|||
login(); |
|||
} |
|||
} |
|||
|
|||
@Override |
|||
public void keyReleased(KeyEvent e) {} |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
SwingUtilities.invokeLater(() -> { |
|||
LoginGUI loginGUI = new LoginGUI(); |
|||
loginGUI.setVisible(true); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,103 @@ |
|||
import javax.swing.*; |
|||
import java.awt.event.ActionEvent; |
|||
import java.awt.event.ActionListener; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
public class SignUpGUI extends JFrame implements ActionListener { |
|||
private JTextField usernameField, passwordField, confirmPasswordField, birthdayField; |
|||
private JButton signUpButton; |
|||
|
|||
public SignUpGUI() { |
|||
setTitle("Sign Up"); |
|||
setSize(300, 250); |
|||
setDefaultCloseOperation(EXIT_ON_CLOSE); |
|||
setLayout(null); |
|||
|
|||
JLabel usernameLabel = new JLabel("Username:"); |
|||
usernameLabel.setBounds(20, 20, 80, 25); |
|||
add(usernameLabel); |
|||
|
|||
usernameField = new JTextField(); |
|||
usernameField.setBounds(100, 20, 160, 25); |
|||
add(usernameField); |
|||
|
|||
JLabel passwordLabel = new JLabel("Password:"); |
|||
passwordLabel.setBounds(20, 50, 80, 25); |
|||
add(passwordLabel); |
|||
|
|||
passwordField = new JPasswordField(); |
|||
passwordField.setBounds(100, 50, 160, 25); |
|||
add(passwordField); |
|||
|
|||
JLabel confirmPasswordLabel = new JLabel("Confirm Password:"); |
|||
confirmPasswordLabel.setBounds(20, 80, 120, 25); |
|||
add(confirmPasswordLabel); |
|||
|
|||
confirmPasswordField = new JPasswordField(); |
|||
confirmPasswordField.setBounds(140, 80, 120, 25); |
|||
add(confirmPasswordField); |
|||
|
|||
JLabel birthdayLabel = new JLabel("Birthday:"); |
|||
birthdayLabel.setBounds(20, 110, 80, 25); |
|||
add(birthdayLabel); |
|||
|
|||
birthdayField = new JTextField(); |
|||
birthdayField.setBounds(100, 110, 160, 25); |
|||
add(birthdayField); |
|||
|
|||
signUpButton = new JButton("Sign Up"); |
|||
signUpButton.setBounds(100, 150, 100, 25); |
|||
signUpButton.addActionListener(this); |
|||
add(signUpButton); |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public void actionPerformed(ActionEvent e) { |
|||
if (e.getSource() == signUpButton) { |
|||
String username = usernameField.getText(); |
|||
String password = passwordField.getText(); |
|||
String confirmPassword = confirmPasswordField.getText(); |
|||
String birthday = birthdayField.getText(); |
|||
|
|||
if (!password.equals(confirmPassword)) { |
|||
JOptionPane.showMessageDialog(this, "Passwords do not match!", "Sign Up Error", JOptionPane.ERROR_MESSAGE); |
|||
return; |
|||
} |
|||
|
|||
if (!isUsernameAvailable("user.json", username)) { |
|||
JOptionPane.showMessageDialog(this, "Username already exists!", "Sign Up Error", JOptionPane.ERROR_MESSAGE); |
|||
return; |
|||
} |
|||
try { |
|||
UUID randomUUID = UUID.randomUUID(); |
|||
CreateUser user = CreateUser.createUser(randomUUID.toString(), username, password, birthday); |
|||
user.saveToJsonFile("user.json"); |
|||
JOptionPane.showMessageDialog(this, "User signed up successfully!"); |
|||
dispose(); |
|||
} catch (IllegalArgumentException ex) { |
|||
JOptionPane.showMessageDialog(this, "Error: " + ex.getMessage(), "Sign Up Error", JOptionPane.ERROR_MESSAGE); |
|||
} |
|||
} |
|||
} |
|||
// Function to check if the input username doesn't already exist in the JSON file |
|||
private boolean isUsernameAvailable(String filename, String username) { |
|||
List<CreateUser> userList = CreateUser.readUserListFromJsonFile(filename); |
|||
if (userList != null) { |
|||
for (CreateUser user : userList) { |
|||
if (user.getUserName().equals(username)) { |
|||
return false; // Username already exists |
|||
} |
|||
} |
|||
} |
|||
return true; // Username is available |
|||
} |
|||
|
|||
public static void main(String[] args) { |
|||
SwingUtilities.invokeLater(() -> { |
|||
SignUpGUI signUpGUI = new SignUpGUI(); |
|||
signUpGUI.setVisible(true); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
[ |
|||
{ |
|||
"id": "a2864d79-1079-4cbb-8d77-f5f84995580d", |
|||
"userName": "Another Test User", |
|||
"password": "TestPasswort123", |
|||
"birthday": "01.01.2000", |
|||
"stayLoggedIn": false |
|||
}, |
|||
{ |
|||
"id": "3690702d-9c7e-48fb-8a01-ef89b3b76268", |
|||
"userName": "TestUser2", |
|||
"password": "123456", |
|||
"birthday": "01.01.2000", |
|||
"stayLoggedIn": false |
|||
}, |
|||
{ |
|||
"id": "685bc3a6-e706-4214-a5e1-8443d1a5258e", |
|||
"userName": "Test User", |
|||
"password": "Test", |
|||
"birthday": "01.01.2000", |
|||
"stayLoggedIn": true |
|||
} |
|||
] |
Write
Preview
Loading…
Cancel
Save
Reference in new issue