CORS Issue: Access-Control-Allow-Origin Header Set to Wildcard * Even When Specific Origins Are Allowed

I am developing a web application using Express.js for the backend and Elementor Frontend, which uses a plugged script to make api calls to the backend. I have implemented CORS (Cross-Origin Resource Sharing) to allow requests from specific origins. However, I’m encountering an issue where the Access-Control-Allow-Origin header is set to *, even when I have specified specific allowed origins.

When I attempt to fetch user data from my backend API, I receive a CORS error in the browser console, stating:

Access to fetch at 'https://b09b-2001-999-580-23c7-cea6-afdc-e9e6-cf43.ngrok-free.app/test' from origin 'https://talopakettiin.fi' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.

The script works for one page just fine, redirects to another one where the script doesn’t seem to gain access giving the above error, even though an origin is specified.

Here is the index.js code:

import express from "express";
import bodyParser from "body-parser";
import cors from "cors";
import dotenv from "dotenv";
import charRoutes from "./routes/charRoutes.js";
import userRoutes from "./routes/userRoutes.js";
import formRoutes from "./routes/formRoutes.js";
import wordPressRoutes from "./routes/wordPressRoutes.js";
import cookieParser from "cookie-parser";

dotenv.config();
const app = express();
const PORT = process.env.PORT || 8000;

// Define allowed origins
const allowedOrigins = [
  "https://talopakettiin.fi",
  "https://b09b-2001-999-580-23c7-cea6-afdc-e9e6-cf43.ngrok-free.app",
];

// CORS options
const corsOptions = {
  origin: allowedOrigins, // Directly allow this origin
  methods: "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS",
  allowedHeaders:
    "Origin, X-Requested-With, Content-Type, Accept, Authorization",
  credentials: true,
};

// Middleware
app.options("*", (req, res) => {
  const origin = allowedOrigins.includes(req.headers.origin)
    ? req.headers.origin
    : null;
  console.log("Here");
  if (origin) {
    res.setHeader("Access-Control-Allow-Origin", origin);
    res.setHeader(
      "Access-Control-Allow-Methods",
      "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS"
    );
    res.setHeader(
      "Access-Control-Allow-Headers",
      "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    );
    res.setHeader("Access-Control-Allow-Credentials", "true");
    res.sendStatus(204); 
  } else {
    res.sendStatus(403); 
  }
});
app.use(cors(corsOptions));
app.use(cookieParser());

// Body Parser Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// Route Handlers
app.use("/chars", charRoutes);
app.use("/user", userRoutes);
app.use("/forms", formRoutes);
app.use("/wordpress", wordPressRoutes);
app.get("/test", (req, res) => {
  console.log("Test endpoint hit");
  res.json({ message: "This is a test." });
});

// Error Handling Middleware
app.use((err, req, res, next) => {
  console.error("Error is here: ", err.stack);
  res.status(500).json({ error: "Something went wrong!" });
});

app.use((req, res, next) => {
  res.on("finish", () => {
    console.log("Response headers:", res.getHeaders());
  });
  next();
});

// Start the server
app.listen(PORT, () =>
  console.log(`Server is running on http://localhost:${PORT}`)
);
 

and here is the script that won’t execute

<!DOCTYPE html>
<html>
  <body>
    <script>
      document.addEventListener("DOMContentLoaded", async function () {
        console.log("At welcome page, Fetching User");

        try {
          const response = await fetch(
            "https://b09b-2001-999-580-23c7-cea6-afdc-e9e6-cf43.ngrok-free.app/test",
            {
              method: "GET",
              credentials: "include",
            }
          );

          console.log("This is the response", response);

          if (response.ok) {
            const contentType = response.headers.get("Content-Type");
            if (contentType && contentType.includes("application/json")) {
              const userData = await response.json();
              document.getElementById(
                "welcomeMessage"
              ).innerText = `Welcome, ${userData.username}!`;
            } else {
              console.error("Unexpected response type:", contentType);
              alert("Unexpected response type from server.");
            }
          } else {
            alert("Failed to fetch user data: " + response.statusText);
          }
        } catch (error) {
          console.error("Error fetching user data:", error.message);
        }
      });
    </script>
  </body>
</html>