Click here to Skip to main content
15,946,342 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
hello I need to create an application that implements a server that communicates with a client and makes me authenticate

What I have tried:

express don't work on my vscode so i don't do anything
Posted

1 solution

Hello before doing everything you have to install express on the folder where you did the project so maybe it doesn't work for you for this
anyway I'll send you my application that allows you to do this

SERVER:
JavaScript
<pre>const express = require('express');
const fs = require('fs');
const http = require('http');
const socketIo = require('socket.io');
const path = require('path');

const app = express();
const server = http.createServer(app);
const io = socketIo(server);

app.use(express.static('public'));
app.use(express.json());

let users = [];
let products = [];

// Funzionalità 1: Caricamento degli utenti dal file
fs.readFile('users.json', (err, data) => {
  if (err && err.code !== 'ENOENT') throw err;
  users = data ? JSON.parse(data) : [];
});

// Funzionalità 2: Caricamento dei prodotti dal file
fs.readFile('products.json', (err, data) => {
  if (err && err.code !== 'ENOENT') throw err;
  products = data ? JSON.parse(data) : [];
});

// Funzionalità 3: Salvataggio degli utenti nel file
const saveUsers = () => {
  fs.writeFile('users.json', JSON.stringify(users), (err) => {
    if (err) throw err;
  });
};

// Funzionalità 4: Salvataggio dei prodotti nel file
const saveProducts = () => {
  fs.writeFile('products.json', JSON.stringify(products), (err) => {
    if (err) throw err;
  });
};

// Funzionalità 5: Gestione registrazione
app.post('/register', (req, res) => {
  const { username, password } = req.body;
  if (users.find(user => user.username === username)) {
    return res.status(400).json({ error: 'User already exists' });
  }
  users.push({ username, password });
  saveUsers();
  res.status(201).json({ success: 'User registered' });
});

// Funzionalità 6: Gestione login
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = users.find(user => user.username === username && user.password === password);
  if (!user) {
    return res.status(401).json({ error: 'Invalid credentials' });
  }
  res.status(200).json({ success: 'Login successful', username });
});

// Funzionalità 7: Gestione aggiunta prodotto
app.post('/add-product', (req, res) => {
  const { name, description, price } = req.body;
  const product = { id: products.length + 1, name, description, price };
  products.push(product);
  saveProducts();
  io.emit('newProduct', product); // Notifica a tutti i client connessi
  res.status(201).json({ success: 'Product added', product });
});

// Funzionalità 8: Gestione rimozione prodotto
app.post('/remove-product', (req, res) => {
  const { id } = req.body;
  products = products.filter(product => product.id !== id);
  saveProducts();
  io.emit('removeProduct', id); // Notifica a tutti i client connessi
  res.status(200).json({ success: 'Product removed' });
});

// Funzionalità 9: Route per la pagina principale
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// Funzionalità 10: Gestione connessione socket.io
io.on('connection', (socket) => {
  console.log('A user connected');
  
  // Funzionalità 10.1: Invia la lista dei prodotti attuali al nuovo client
  socket.emit('productList', products);

  // Funzionalità 10.2: Gestione dei messaggi di chat
  socket.on('chatMessage', (msg) => {
    io.emit('chatMessage', msg);
  });
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});


CLIENT:

HTML
<pre><!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Authentication and Chat</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <h1>Authentication</h1>
  
    <!-- Funzionalità 1: Modulo di login -->
    <div id="login">
      <h2>Login</h2>
      <form id="loginForm">
        <label for="loginUsername">Username:</label>
        <input type="text" id="loginUsername" name="username" required>
        <br>
        <label for="loginPassword">Password:</label>
        <input type="password" id="loginPassword" name="password" required>
        <br>
        <button type="submit">Login</button>
      </form>
      <p id="loginMessage"></p>
      <p>Sei registrato? <a href="#" id="showRegister">Registrati</a></p>
    </div>

    <!-- Funzionalità 2: Modulo di registrazione -->
    <div id="register" style="display: none;">
      <h2>Register</h2>
      <form id="registerForm">
        <label for="registerUsername">Username:</label>
        <input type="text" id="registerUsername" name="username" required>
        <br>
        <label for="registerPassword">Password:</label>
        <input type="password" id="registerPassword" name="password" required>
        <br>
        <button type="submit">Register</button>
      </form>
      <p id="registerMessage"></p>
      <p>Hai già un account? <a href="#" id="showLogin">Login</a></p>
    </div>

    <!-- Funzionalità 3: Chat -->
    <div id="chat" style="display: none;">
      <h2>Chat</h2>
      <div id="messages"></div>
      <form id="chatForm">
        <input type="text" id="message" autocomplete="off" required>
        <button type="submit">Send</button>
      </form>
    </div>

    <!-- Funzionalità 4: Lista dei prodotti -->
    <div id="products" style="display: none;">
      <h2>Products</h2>
      <div id="productList"></div>
    </div>

    <!-- Funzionalità 5: Modulo di aggiunta prodotto -->
    <div id="addProduct" style="display: none;">
      <h2>Add Product</h2>
      <form id="addProductForm">
        <label for="productName">Name:</label>
        <input type="text" id="productName" name="name" required>
        <br>
        <label for="productDescription">Description:</label>
        <input type="text" id="productDescription" name="description" required>
        <br>
        <label for="productPrice">Price:</label>
        <input type="number" id="productPrice" name="price" required>
        <br>
        <button type="submit">Add Product</button>
      </form>
    </div>
  </div>

  <!-- Funzionalità 6: Modal per la visualizzazione dei dettagli del prodotto -->
  <div id="productModal" class="modal" style="display: none;">
    <div class="modal-content">
      ×
      <h2 id="modalProductName"></h2>
      <p id="modalProductDescription"></p>
      <p id="modalProductPrice"></p>
    </div>
  </div>

  <script src="/socket.io/socket.io.js"></script>
  <script>
    const socket = io();

    let currentUser = '';

    // Funzionalità 1: Login
    const loginForm = document.getElementById('loginForm');
    const registerForm = document.getElementById('registerForm');
    const loginMessage = document.getElementById('loginMessage');
    const registerMessage = document.getElementById('registerMessage');
    const showRegisterLink = document.getElementById('showRegister');
    const showLoginLink = document.getElementById('showLogin');

    // Eventi per mostrare/nascondere moduli
    showRegisterLink.addEventListener('click', () => {
      document.getElementById('login').style.display = 'none';
      document.getElementById('register').style.display = 'block';
    });

    showLoginLink.addEventListener('click', () => {
      document.getElementById('register').style.display = 'none';
      document.getElementById('login').style.display = 'block';
    });

    // Login form submission
    loginForm.addEventListener('submit', (e) => {
      e.preventDefault();
      const username = loginForm.loginUsername.value;
      const password = loginForm.loginPassword.value;

      fetch('/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ username, password }),
      })
      .then(response => response.json())
      .then(data => {
        if (data.error) {
          loginMessage.textContent = data.error;
        } else {
          loginMessage.textContent = data.success;
          currentUser = username;
          document.getElementById('login').style.display = 'none';
          document.getElementById('register').style.display = 'none';
          document.querySelector('.container').style.width = '800px';
          document.getElementById('chat').style.display = 'block';
          document.getElementById('products').style.display = 'block';
          document.getElementById('addProduct').style.display = 'block';
        }
      });
    });

    // Funzionalità 2: Registrazione
    registerForm.addEventListener('submit', (e) => {
      e.preventDefault();
      const username = registerForm.registerUsername.value;
      const password = registerForm.registerPassword.value;

      fetch('/register', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ username, password }),
      })
      .then(response => response.json())
      .then(data => {
        if (data.error) {
          registerMessage.textContent = data.error;
        } else {
          registerMessage.textContent = data.success;
        }
      });
    });

    // Funzionalità 3: Chat
    const chatForm = document.getElementById('chatForm');
    const messageInput = document.getElementById('message');
    const messages = document.getElementById('messages');
    chatForm.addEventListener('submit', (e) => {
      e.preventDefault();
      const msg = { user: currentUser, text: messageInput.value };
      socket.emit('chatMessage', msg);
      messageInput.value = '';
    });

    socket.on('chatMessage', (msg) => {
      const item = document.createElement('div');
      item.textContent = `${msg.user}: ${msg.text}`;
      messages.appendChild(item);
    });

    // Funzionalità 4: Gestione prodotti
    const addProductForm = document.getElementById('addProductForm');
    const productList = document.getElementById('productList');
    addProductForm.addEventListener('submit', (e) => {
      e.preventDefault();
      const name = addProductForm.productName.value;
      const description = addProductForm.productDescription.value;
      const price = addProductForm.productPrice.value;

      fetch('/add-product', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ name, description, price }),
      })
      .then(response => response.json())
      .then(data => {
        if (data.success) {
          addProductToList(data.product);
          addProductForm.reset();
        }
      });
    });

    socket.on('newProduct', (product) => {
      addProductToList(product);
    });

    socket.on('removeProduct', (id) => {
      const productItem = document.getElementById(`product-${id}`);
      if (productItem) {
        productItem.remove();
      }
    });

    socket.on('productList', (products) => {
      productList.innerHTML = '';
      products.forEach(product => {
        addProductToList(product);
      });
    });

    function addProductToList(product) {
      if (!document.getElementById(`product-${product.id}`)) {
        const productItem = document.createElement('div');
        productItem.id = `product-${product.id}`;
        productItem.innerHTML = `
          ${product.name}
          <button onclick="removeProduct(${product.id})">Remove</button>
        `;
        productList.appendChild(productItem);

        const productNameElement = productItem.querySelector('.product-name');
        productNameElement.addEventListener('click', () => {
          showModal(product);
        });
      }
    }

    // Funzionalità 5: Modale per la visualizzazione del prodotto
    function showModal(product) {
      const modal = document.getElementById('productModal');
      document.getElementById('modalProductName').textContent = product.name;
      document.getElementById('modalProductDescription').textContent = `Description: ${product.description}`;
      document.getElementById('modalProductPrice').textContent = `Price: ${product.price}`;
      modal.style.display = 'block';

      const closeModal = document.querySelector('.close');
      closeModal.onclick = function() {
        modal.style.display = 'none';
      }

      window.onclick = function(event) {
        if (event.target === modal) {
          modal.style.display = 'none';
        }
      }
    }

    window.removeProduct = function(id) {
      fetch('/remove-product', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ id }),
      })
      .then(response => response.json())
      .then(data => {
        if (data.success) {
          const productItem = document.getElementById(`product-${id}`);
          if (productItem) {
            productItem.remove();
          }
        }
      });
    }
  </script>
</body>
</html>


STYLE:

CSS
/* Funzionalità 1: Stile per il corpo della pagina */
body {
  font-family: 'Arial', sans-serif;
  background: linear-gradient(to right, #ff7e5f, #feb47b);
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
}

/* Funzionalità 2: Stile per il container principale */
.container {
  background-color: #fff;
  padding: 40px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  border-radius: 15px;
  width: 400px;
  text-align: center;
  transition: all 0.3s ease-in-out;
}

.container:hover {
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}

/* Funzionalità 3: Stile per gli header */
h1 {
  margin-bottom: 20px;
  font-size: 24px;
  color: #333;
}

h2 {
  margin-bottom: 20px;
  font-size: 20px;
  color: #333;
}

/* Funzionalità 4: Stile per gli input di testo e password */
input[type="text"], input[type="password"] {
  width: calc(100% - 40px);
  padding: 10px;
  margin: 10px 0;
  border: 1px solid #ccc;
  border-radius: 25px;
  box-sizing: border-box;
  transition: all 0.3s ease-in-out;
}

input[type="text"]:focus, input[type="password"]:focus {
  border-color: #ff7e5f;
  box-shadow: 0 0 8px rgba(255, 126, 95, 0.2);
  outline: none;
}

/* Funzionalità 5: Stile per i pulsanti */
button {
  width: calc(100% - 40px);
  padding: 10px;
  background-color: #ff7e5f;
  border: none;
  border-radius: 25px;
  color: #fff;
  cursor: pointer;
  margin: 20px 0;
  transition: all 0.3s ease-in-out;
}

button:hover {
  background-color: #feb47b;
}

/* Funzionalità 6: Stile per i paragrafi */
p {
  margin: 10px 0 0;
  color: #555;
}

/* Funzionalità 7: Stile per i link */
a {
  color: #ff7e5f;
  text-decoration: none;
  transition: color 0.3s ease-in-out;
}

a:hover {
  color: #feb47b;
  text-decoration: underline;
}

/* Funzionalità 8: Stile per la chat */
.chat-container {
  text-align: left;
}

#messages {
  list-style-type: none;
  padding: 0;
  margin: 0;
  height: 200px;
  overflow-y: scroll;
  border: 1px solid #ccc;
  border-radius: 10px;
  padding: 10px;
}

#messages div {
  padding: 5px 10px;
  border-bottom: 1px solid #eee;
}

#message {
  width: calc(100% - 40px);
  padding: 10px;
  margin: 10px 0;
  border: 1px solid #ccc;
  border-radius: 25px;
  box-sizing: border-box;
  transition: all 0.3s ease-in-out;
}

/* Funzionalità 9: Stile per la lista dei prodotti */
#productList {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

#productList div {
  padding: 10px;
  border-bottom: 1px solid #ccc;
  display: flex;
  justify-content: space-between;
}

#productList div span {
  cursor: pointer;
  color: #ff7e5f;
}

#productList div span:hover {
  text-decoration: underline;
}

/* Funzionalità 10: Stile per la modale */
.modal {
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgb(0,0,0);
  background-color: rgba(0,0,0,0.4);
  padding-top: 60px;
}

.modal-content {
  background-color: #fefefe;
  margin: 5% auto;
  padding: 20px;
  border: 1px solid #888;
  width: 80%;
  border-radius: 15px;
}

.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900