Database :

const mongoose = require("mongoose");

mongoose.connect(
    "mongodb+srv://moussa:<PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>/mongoglcc",
    {
        useNewUrlParser: true,
        useUnifiedTopology: true,
    },
);

const db = mongoose.connection;

db.on("error", console.error.bind(console, "MongoDB connection error:"));

module.exports = db;


Backend :

const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const bcrypt = require("bcrypt");
const session = require("express-session");
const db = require('./config/db');
const User = require("./models/user");
const News = require("./models/news");

const index = express();
const port = process.env.PORT || 5000;

// Middleware
index.use(
    cors(),
);
index.use(bodyParser.json());
index.use(cookieParser());

// Session setup
index.use(
    session({
      secret: "your-secret-key",
      resave: false,
      saveUninitialized: true,
      cookie: {
        sameSite: "none",
        secure: true,
      },
    }),
);

{
  /*********************************************************************/
}

index.post("/signup", async (req, res) => {
  try {
    const { username, password } = req.body;

    // Check if the username already exists
    const existingUser = await User.findOne({ username });
    if (existingUser) {
      return res.status(400).json({ error: "exists" });
    }

    // Hash the password
    const hashedPassword = await bcrypt.hash(password, 10);

    // Create a new user and save to the database
    const user = new User({ username, password: hashedPassword });
    await user.save();

    res.status(201).json({ message: "User created successfully" });
  } catch (error) {
    if (error.code === 11000 && error.keyValue && error.keyValue.username) {
      // Duplicate key error, indicating that the username already exists
      return res.status(400).json({ error: "exists" });
    }
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

index.post("/signin", async (req, res) => {
  try {
    const { username, password } = req.body;

    const user = await User.findOne({ username });

    if (!user || !(await bcrypt.compare(password, user.password))) {
      return res.status(401).json({ error: "Authentication failed" });
    }

    req.session.user = user;

    res.json({ message: "Authentication successful", redirect: "/home" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

index.get("/checkLoggedIn", (req, res) => {
  if (req.session.user) {
    res
        .status(200)
        .json({ loggedIn: true, username: req.session.user.username });
  } else {
    res.status(401).json({ loggedIn: false });
  }
});

{
  /*********************************************************************/
}

// Helper function to validate URL format
function isValidURL(url) {
  // Basic URL format check (you might want to use a more sophisticated check)
  const urlPattern =
      /^(https?:\/\/)?(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}(\/\S*)?$/;
  return urlPattern.test(url);
}

// Fetch list of news articles
index.get("/news/all", async (req, res) => {
  try {
    const newsList = await News.find();
    res.status(200).json({ news: newsList });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred while fetching news" });
  }
});

// Check if a URL is unique
index.post("/news/add", async (req, res) => {
  try {
    const { userId, url, title } = req.body;

    // Check if the URL is unique
    const existingNews = await News.findOne({ url });
    if (existingNews) {
      return res.status(400).json({ error: "URL already exists" });
    }

    const news = new News({
      userId,
      url,
      title,
      likes: 0,
      dislikes: 0,
      comments: [],
    });
    await news.save();

    res.status(201).json({ message: "TraiteReponseNews added successfully" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

// Check URL format route
index.get("/news/checkUrlFormat/:url", (req, res) => {
  const { url } = req.params;

  // Validate URL format (this is a basic check)
  if (!isValidURL(url)) {
    return res.status(400).json({ validFormat: false });
  }

  res.status(200).json({ validFormat: true });
});

// Check URL uniqueness route
index.get("/news/checkUrl/:url", async (req, res) => {
  const { url } = req.params;

  try {
    const existingNews = await News.findOne({ url });
    const isUnique = !existingNews;

    res.status(200).json({ unique: isUnique });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

// Add Comment route
index.post("/news/addComment/:id", async (req, res) => {
  const { id } = req.params;
  const { auteur, commentaire } = req.body;

  try {
    const news = await News.findById(id);

    if (!news) {
      return res
          .status(404)
          .json({ error: "TraiteReponseNews article not found" });
    }

    news.comments.push({
      date: new Date(),
      auteur,
      commentaire,
    });

    await news.save();

    res.status(200).json({ message: "Comment added successfully" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

// API route to like news article
// Like a news article
index.post("/news/like/:id", async (req, res) => {
  const { id } = req.params;
  const { loggedInUsername } = req.body;

  try {
    const news = await News.findById(id);

    if (!news) {
      return res.status(404).json({ error: "News article not found" });
    }

    const user = await User.findOne({ username: loggedInUsername });

    if (!user) {
      return res.status(404).json({ error: "User not found" });
    }

    if (user.likedNews.includes(id)) {
      return res
          .status(400)
          .json({ error: "User has already liked this article" });
    }

    if (user.dislikedNews.includes(id)) {
      // Remove from dislikedNews array
      user.dislikedNews.pull(id);
      await user.save();
      news.dislikes -= 1;
    }

    user.likedNews.push(id);
    await user.save();
    news.likes += 1;
    await news.save();

    res.status(200).json({ message: "News article liked successfully" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

// Dislike a news article
index.post("/news/dislike/:id", async (req, res) => {
  const { id } = req.params;
  const { loggedInUsername } = req.body;

  try {
    const news = await News.findById(id);

    if (!news) {
      return res.status(404).json({ error: "News article not found" });
    }

    const user = await User.findOne({ username: loggedInUsername });

    if (!user) {
      return res.status(404).json({ error: "User not found" });
    }

    if (user.dislikedNews.includes(id)) {
      return res
          .status(400)
          .json({ error: "User has already disliked this article" });
    }

    if (user.likedNews.includes(id)) {
      // Remove from likedNews array
      user.likedNews.pull(id);
      await user.save();
      news.likes -= 1;
    }

    user.dislikedNews.push(id);
    await user.save();
    news.dislikes += 1;
    await news.save();

    res.status(200).json({ message: "News article disliked successfully" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

{
  /*********************************************************************/
}
index.post("/addFriend/:username", async (req, res) => {
  try {
    const { username } = req.params;
    const { friendUsername } = req.body;

    const loggedInUser = await User.findOne({ username });

    if (!loggedInUser) {
      return res.status(404).json({ error: "User not found" });
    }

    if (loggedInUser.friends.includes(friendUsername)) {
      return res.status(400).json({ error: "Friend already exists" });
    }

    loggedInUser.friends.push(friendUsername);
    await loggedInUser.save();

    res.status(200).json({ message: "Friend added successfully" });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

// Friends endpoint
index.get("/friends/:username", async (req, res) => {
  const { username } = req.params;

  try {
    const user = await User.findOne({ username });

    if (!user) {
      return res.status(404).json({ error: "User not found" });
    }

    // Return the friends array from the user document
    res.status(200).json({ friends: user.friends });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Server error" });
  }
});

index.get("/users", async (req, res) => {
  try {
    const users = await User.find({}, "username");
    res.status(200).json(users);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "An error occurred" });
  }
});

index.get("/likedNews/:username", async (req, res) => {
  const { username } = req.params;

  // Validate and sanitize page parameter
  const page = parseInt(req.query.page) || 1;

  try {
    // Find user by username
    const user = await User.findOne({ username })
        .populate("likedNews") // Populate reference
        .exec();

    if (!user) {
      return res.status(404).json({ message: "User not found" });
    }

    // Pagination variables
    const pageSize = 3;
    const skip = pageSize * (page - 1);

    // Slice likedNews array
    const likedNews = user.likedNews.slice(skip, skip + pageSize);

    // Total count
    const total = user.likedNews.length;

    // Calculate total pages
    const totalPages = Math.ceil(total / pageSize);

    res.json({
      likedNews,
      total,
      totalPages,
      currentPage: page,
    });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

module.exports = index; // Export the index object


MODELS :

const mongoose = require("mongoose");

const newsSchema = new mongoose.Schema({
    userId: {
        type: String,
        required: true,
    },
    url: {
        type: String,
        required: true,
        unique: true,
    },
    title: {
        type: String,
        required: true,
    },
    likes: {
        type: Number,
        default: 0,
    },
    dislikes: {
        type: Number,
        default: 0,
    },
    comments: {
        type: [
            {
                date: {
                    type: Date,
                    required: true,
                },
                auteur: {
                    type: String,
                    required: true,
                },
                commentaire: {
                    type: String,
                    required: true,
                },
            },
        ],
        default: [],
    },
});

// Virtual field to calculate the score (likes - dislikes)
newsSchema.virtual("score").get(function () {
    return this.likes - this.dislikes;
});

newsSchema.set("toJSON", { virtuals: true });

const News = mongoose.model("News", newsSchema);

module.exports = News;


const mongoose = require("mongoose");

const userSchema = new mongoose.Schema({
    username: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    friends: [{ type: String }],
    likedNews: [{ type: mongoose.Schema.Types.ObjectId, ref: "News" }],
    dislikedNews: [{ type: mongoose.Schema.Types.ObjectId, ref: "News" }],
});

const User = mongoose.model("User", userSchema);

module.exports = User;

transform this into flask