1

I have a project for log in and sign up. Everything works on the local environment. After registering an account, it is sent to the database. If I try to register an account with the same information again, it is not possible because I receive a message saying that it already exists. If the account was created on the local environment, logging in is possible. However, after registering an account, I cannot log in as I get an error 401 (Unauthorized).

server.js

    const express = require('express');
    const app = express();
    const path = require('path');
    const cors = require('cors');
    const corsOptions = require('./config/corsOptions');
    const { logger } = require('./middleware/logEvents');
    const errorHandler = require('./middleware/errorHandler');
    const verifyJWT = require('./middleware/verifyJWT');
    const cookieParser = require('cookie-parser');
    const credentials = require('./middleware/credentials');
    const PORT = process.env.PORT || 3500;
    // custom middleware logger
    app.use(logger);

    // Handle options credentials check - before CORS!
    // and fetch cookies credentials requirement
    app.use(credentials);

    // Cross Origin Resource Sharing
    app.use(cors(corsOptions));

    // built-in middleware to handle urlencoded form data
    app.use(express.urlencoded({ extended: false }));

    // built-in middleware for json 
    app.use(express.json());

    //middleware for cookies
    app.use(cookieParser());

    //serve static files
    app.use('/', express.static(path.join(__dirname, '/public')));

    // routes
    app.use('/', require('./routes/root'));
    app.use('/register', require('./routes/register'));
    app.use('/auth', require('./routes/auth'));
    app.use('/refresh', require('./routes/refresh'));
    app.use('/logout', require('./routes/logout'));

    app.use(verifyJWT);
    app.use('/employees', require('./routes/api/employees'));

    app.all('*', (req, res) => {
        res.status(404);
        if (req.accepts('html')) {
            res.sendFile(path.join(__dirname, 'views', '404.html'));
        } else if (req.accepts('json')) {
            res.json({ "error": "404 Not Found" });
        } else {
            res.type('txt').send("404 Not Found");
        }
    });

    app.use(errorHandler);

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

auth.js

    const express = require('express');
    const router = express.Router();
    const authController = require('../controllers/authController');

    router.post('/', authController.handleLogin);

    module.exports = router;

authController.js

    const usersDB = {
        users: require('../model/users.json'),
        setUsers: function (data) {
            this.users = data;
        },
    };
    const bcrypt = require('bcrypt');

    const jwt = require('jsonwebtoken');
    require('dotenv').config();
    const fsPromises = require('fs').promises;
    const path = require('path');

    const handleLogin = async (req, res) => {
        const { user, pwd } = req.body;
        if (!user || !pwd)
            return res
                .status(400)
                .json({ message: 'Username and password are required.' });
        const foundUser = usersDB.users.find((person) => person.username === user);
        if (!foundUser) return res.sendStatus(401); //Unauthorized
        // evaluate password
        const match = await bcrypt.compare(pwd, foundUser.password);
        if (match) {
            const roles = Object.values(foundUser.roles).filter(Boolean);
            // create JWTs
            const accessToken = jwt.sign(
                {
                    UserInfo: {
                        "username": foundUser.username,
                        roles: roles,
                    },
                },
                process.env.ACCESS_TOKEN_SECRET,
                { expiresIn: '30s' }
            );
            const refreshToken = jwt.sign(
                { "username": foundUser.username },
                process.env.REFRESH_TOKEN_SECRET,
                { expiresIn: '1d' }
            );

            // Saving refreshToken with current user
            const otherUsers = usersDB.users.filter(
                (person) => person.username !== foundUser.username
            );
            const currentUser = { ...foundUser, refreshToken };
            usersDB.setUsers([...otherUsers, currentUser]);
            await fsPromises.writeFile(
                path.join(__dirname, '..', 'model', 'users.json'),
                JSON.stringify(usersDB.users)
            );
            res.cookie('jwt', refreshToken, {
                httpOnly: true,
                sameSite: 'None',
                secure: true,
                maxAge: 24 * 60 * 60 * 1000,
            });
            res.json({ accessToken });
        } else {
            res.sendStatus(401);
        }
    };

    module.exports = { handleLogin };

I added an env file with a token. I added variables with tokens in Render.

1 Answers1

0

i think this is wrong statement, and you miss await

const foundUser = usersDB.users.find((person) => person.username === user)

it should be:

const foundUser = await usersDB.users.find({username: user})
Tobok Sitanggang
  • 607
  • 5
  • 15