Home > front end >  The app works fine with localhost but Heroku gives bad request error when trying to login or signup
The app works fine with localhost but Heroku gives bad request error when trying to login or signup

Time:11-24

I have my first node.js app (runs fine locally) - but Heroku gives Bad Request(400) error when trying to login or sign up (first time heroku as well). The code is below. I would say that the running the code locally as well within my network shows no issue. I didn't understand if the problem comes from the frontend request.

And the code: index.js:

const express = require("express");
const loggerMiddleWare = require("morgan");
const cors = require("cors");
const { PORT } = require("./config/constants");
const authRouter = require("./routers/auth");
const artworkRouter = require("./routers/artworks");
const bodyParserMiddleWare = express.json();
const app = express();

app.use(loggerMiddleWare("dev"));
app.use(bodyParserMiddleWare);
app.use(cors());

if (process.env.DELAY) {
  app.use((req, res, next) => {
    setTimeout(() => next(), parseInt(process.env.DELAY));
  });
}

app.use("/", authRouter);
app.use("/artworks", artworkRouter);

app.listen(PORT, () => {
  console.log(`Listening on port: ${PORT}`);
});

auth.js

const bcrypt = require("bcrypt");
const { Router } = require("express");
const { toJWT } = require("../auth/jwt");
const authMiddleware = require("../auth/middleware");
const User = require("../models/").user;
const { SALT_ROUNDS } = require("../config/constants");

const router = new Router();

router.post("/login", async (req, res, next) => {
  try {
    console.log(`Before const { email, password } = req.body;`);
    const { email, password } = req.body;
    console.log(`After const { email, password } = req.body;`);

    if (!email || !password) {
      return res
        .status(400)
        .send({ message: "Please provide both email and password" });
    }

    console.log(`Before await User.findOne({ where: { email } });`);
    const user = await User.findOne({ where: { email } });
    console.log(`After await User.findOne({ where: { email } });`);

    if (!user || !bcrypt.compareSync(password, user.password)) {
      return res.status(400).send({
        message: "User with that email not found or password incorrect",
      });
    }

    delete user.dataValues["password"]; // don't send back the password hash
    const token = toJWT({ userId: user.id });
    return res.status(200).json({ token, ...user.dataValues });
  } catch (error) {
    console.log(error);
    return res.status(400).send({
      message: `Login Page: Something went wrong, sorry: ${JSON.stringify(
        req.headers
      )}, AND, ${JSON.stringify(req.body)}
      )}`,
    });
  }
});

router.post("/signup", async (req, res) => {
  const { email, password, name, isArtist } = req.body;
  if (!email || !password || !name) {
    return res.status(400).send("Please provide an email, password and a name");
  }

  try {
    const newUser = await User.create({
      email,
      password: bcrypt.hashSync(password, SALT_ROUNDS),
      name,
      isArtist,
    });

    delete newUser.dataValues["password"]; // don't send back the password hash

    const token = toJWT({ userId: newUser.id });

    res.status(201).json({ token, ...newUser.dataValues });
  } catch (error) {
    if (error.name === "SequelizeUniqueConstraintError") {
      return res
        .status(400)
        .send({ message: "There is an existing account with this email" });
    }

    return res
      .status(400)
      .send({ message: "Signup Page: Something went wrong, sorry" });
  }
});

module.exports = router;

config.js:

require("dotenv").config();

module.exports = {
  development: {
    url: process.env.DB_URL,
    dialect: "postgres",
    operatorsAliases: "0",
  },
  test: {
    username: "root",
    password: null,
    database: "database_test",
    host: "127.0.0.1",
    dialect: "postgres",
    operatorsAliases: "0",
  },
  production: {
    use_env_variable: "DATABASE_URL",
    dialectOptions: {
      ssl: {
        rejectUnauthorized: false,
      },
    },
    dialect: "postgres",
  },
};

constants.js:

require("dotenv").config();

module.exports = {
  SALT_ROUNDS: 10,
  PORT: process.env.PORT || 4000,
};

Procfile:

release: bash post-release.sh

post-release.sh:

npx sequelize-cli db:migrate

I have also a .env file

DB_URL=postgres....
JWT_SECRET=....

Any idea?

CodePudding user response:

I've seen that there was an error in auth middleware:

JsonWebTokenError: secret or public key must be provided.

This means my application can't read the environment variable properly. I've fixed this problem to change toJWT function. It uses jwt.sign(data, jwtSecret, { expiresIn: "1h" }) function. I've changed jwtSecret as "" jwtSecret as in the succession there: https://stackoverflow.com/a/62350806/15018495.

  • Related