Routes Problem with node.js 404 not found

20 Views Asked by At

I tried creating a user authentication with MERN stack, the authentication also has a verification link so user have to verify before logging in, but the mail is sent to user successfully but, the link is throwing error "404 not found" I'll provide the code below:

**App.js**
import './App.css';
import Tracking from './Page/Tracking';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Login from './Page/Login';
import SignUp from './Page/SignUp';
import 'bootstrap/dist/css/bootstrap.min.css';
import AirlinesList from './Page/AirlinesList';
import EmailVerify from './verify';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/login" element={<Login />} />
        <Route path="/" element={<Tracking />} />
        <Route path="/signup" element={<SignUp />} />
        <Route path="/airline-list" element={<AirlinesList />} />
        <Route path="/users/:id/verify/:token" element={<EmailVerify />} />
      </Routes>
    </Router>
  );
}

export default App;

**Backend server.js**
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const { UserModel, MyModel, TrackedAwbModel } = require('./modules/schema');
const bcrypt = require('bcrypt');
const nodemailer = require('nodemailer');
const mongoose = require('mongoose');
require('dotenv/config')
const Token = require('./modules/token')
const sendEmail = require('./sendEmail')
const crypto = require('crypto');

const app = express()
app.use(cors())
var http = require('http');

http.createServer(function (request, response) {
    response.writeHead(200, {
        'Content-Type': 'text/plain',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
    });
    response.end('Hello World\n');
}).listen(400);
app.use(express.json())

mongoose.connect(process.env.DB_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}).then(() => {
    console.log('Connected to MongoDB');
}).catch(err => {
    console.error('Error connecting to MongoDB', err);
});

app.get('/data', async (req, res) => {
    try {
        const data = await MyModel.find();
        res.json(data);
    } catch (error) {
        res.status(500).json({ error: 'Internal server error' });
    }
});

app.post('/users', async (req, res) => {
    const { name, designation, email, companyName, mobileno, password } = req.body;
    try {
        const existingUser = await UserModel.findOne({ email: email });
        if (existingUser) {
            return res.status(400).json({ error: "Email or username already exists" });
        }

        const hashedPassword = await bcrypt.hash(password, 10);
        const newUser = await UserModel.create({ name, designation, email, companyName, mobileno, password: hashedPassword });
        user = await new UserModel({ ...req.body, password: hashedPassword }).save();

        const token = await new Token({
            userId: user._id,
            token: crypto.randomBytes(32).toString("hex")
        }).save();

        const url = `http://localhost:3000/users/${user._id}/verify/${token.token}`;
        await sendEmail(user.email, "Verify Air Track", url);

        res.json({ message: "User created successfully, Verify your email", userId: newUser._id });
    }
    catch (error) {
        console.error(error);
        res.status(500).json({ error: 'Internal server error' });
    }
})

app.get("/:id/verify/:token", async (req, res) => {
    try {
        const user = await UserModel.findOne({ _id: req.params.id });
        if (!user) return res.status(400).send({ message: "Invalid link" });

        const token = await Token.findOne({
            userId: user._id,
            token: req.params.token
        });
        if (!token) return res.status(400).send({ message: "Invalid link" });

        await UserModel.updateOne({ _id: user._id, isEmailVerified: true })
        await token.remove()

        res.status(200).send({ message: "Email Verified Succesfully" })
    } catch (error) {
        res.status(500).json({ error: 'Internal server error' });
    }
})

app.post('/login', async (req, res) => {
    const { email, password } = req.body;

    try {
        const user = await UserModel.findOne({ email });
        const passwordMatch = await bcrypt.compare(password, user.password);

        if (!passwordMatch) {
            return res.status(401).json({ error: "Invalid password" });
        }

        if (!user.isEmailVerified) {
            let token = await Token.findOne({ userId: user._id });
            if (!token) {
                token = await new Token({
                    userId: user._id,
                    token: crypto.randomBytes(32).toString("hex")
                }).save();
                const url = `${process.env.BASE_URL}users/${userd._id}/verify/${token.token}`
                await sendEmail(user.email, "Verify Air Track", url);
            }
            return res.status(401).json({ error: "Email not verified" })
        }

        res.json({ message: "Login successful", user });
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: 'Internal server error' });
    }
});


const port = process.env.PORT || 4000
const server = app.listen(port, () => {
    console.log(`Server running on port ${port}`)
})


**SendEmail.js**
const nodemailer = require('nodemailer')
require('dotenv/config')

module.exports = async (email, subject, text) => {
    try {
        const transporter = nodemailer.createTransport({
            host: process.env.SMTP_HOST,
            port: process.env.SMTP_PORT,
            secure: false,
            auth: {
                user: process.env.EMAIL_USERNAME,
                pass: process.env.EMAIL_PASSWORD
            }
        });

        await transporter.sendMail({
            from: process.env.EMAIL_USERNAME,
            to: email,
            subject: subject,
            text: text
        })
        console.log("Email sent succesfully");
    } catch (error) {
        console.log("Email not sent");
        console.log(error)
    }
}
**SignUp page** 
import React, { useState } from "react"
import "./Styles/Login.css"
import { Link } from "react-router-dom";
import axios from "axios";
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

function SignUp() {
    const [formData, setFormData] = useState({
        name: "",
        designation: "",
        companyName: "",
        email: "",
        mobileno: "",
        password: "",
        otp: ""
    });
    const [error, setError] = useState("");
    const [successMessage, setSuccessMessage] = useState("");
    const [msg, setMsg] = useState("");
    const [isSubmitting, setIsSubmitting] = useState(false);

    const handleChange = (e) => {
        setFormData({
            ...formData,
            [e.target.name]: e.target.value
        });
    };

    const handleSubmit = (e) => {
        e.preventDefault();

        if (isSubmitting) {
            return;
        }

        setIsSubmitting(true);

        axios.post("http://localhost:4000/users", formData)
            .then(response => {
                setFormData({
                    name: "",
                    designation: "",
                    companyName: "",
                    email: "",
                    mobileno: "",
                    password: "",
                });
                setError("");
                setMsg(response.msg)
            })
            .catch(error => {
                if (error.response) {
                    if (error.response.status === 400) {
                        toast.error("Email or username already exists");
                    } else {
                        toast.error("An error occurred. Please try again later.");
                    }
                } else {
                    toast.error("Network error. Please check your internet conneciton");
                }
            }).finally(() => {
                setIsSubmitting(false);
            });
    };

    return (
        <div className="login">
            <h1 className="log-head" style={{ marginBottom: '20px' }}>Sign up</h1>
            <div>
                <form className="log-form" onSubmit={handleSubmit}>
                    <span className="input-row">
                        <div className="user-input">
                            <label htmlFor="name">Name:</label>
                            <input type="text" placeholder="Enter name" name="name" id="name" required
                                value={formData.name}
                                onChange={handleChange} />
                        </div>
                        <div className="user-input">
                            <label htmlFor="designaiton">Designation:</label>
                            <input type="text" placeholder="Enter designation" name="designation" id="designation" required
                                value={formData.designation}
                                onChange={handleChange} />
                        </div>
                    </span>
                    <span className="input-row">
                        <div className="user-input">
                            <label htmlFor="company-name">Company Name:</label>
                            <input type="text" placeholder="Enter company name" name="companyName" id="company-name" required
                                value={formData.companyName}
                                onChange={handleChange} />
                        </div>
                        <div className="user-input">
                            <label htmlFor="input">Company Email:</label>
                            <input type="email" placeholder="Enter company email" name="email" id="input" required
                                value={formData.email}
                                onChange={handleChange} />
                        </div>
                    </span>
                    <span className="input-row">
                        <div className="user-input">
                            <label htmlFor="username">Mobile no:</label>
                            <input type="number" placeholder="Enter mobile-no" name="mobileno" id="mobileno" required
                                value={formData.mobileno}
                                onChange={handleChange} />
                        </div>
                        <div className="user-input">
                            <label htmlFor="password">Password:</label>
                            <input type="password" placeholder="Enter password" name="password" id="password" required
                                value={formData.password}
                                onChange={handleChange} />
                        </div>
                    </span>
                    <div >
                        <input type="checkbox" id="horns" name="horns" required />
                        <label htmlFor="horns">I agree to terms and conditions</label>
                    </div>

                    {error && <p className="error-message">{error}</p>}
                    {msg && <p className="success-message">{msg}</p>}
                    <p className="sign-para">Already a user? <Link to='/login'>Log In</Link></p>
                    <button className="login-btn" type="submit">
                        Sign up
                    </button>

                </form>
            </div >
            <ToastContainer />
        </div >

    )
};
export default SignUp;

I params and changed to const [id, token] = UseParams() it gives me AxiosError.

0

There are 0 best solutions below