最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

node.js - Which data should I fetch from database to leave classroom? - Stack Overflow

programmeradmin0浏览0评论

I'm building a MERN project i.e. a Teacher's forum application where teachers can create their own classroom & give access to particular students through OTP service. But while I'm building a route for student user which "leave" means under every classroom there is a leave button which when clicked student should leave a classroom.

The code through which you'll get an idea:

// route for leave classroom
router.delete('/leave/:classid', authTokenHandler, async (req, res) => {
    const { classid } = req.params;
    console.log("From classroom: ", classid);
    const userEmail = req.user?.email; // Get the authenticated user's email
    console.log("Email: ", userEmail);
    

    try {
        // Find and delete the student's entry from the classroomJoin collection
        const classroomEntry = await ClassroomJoin.findOneAndDelete({
            classroomId: classid,
            studentEmail: userEmail
        });

        if (!classroomEntry) {
            return res.status(400).json({ message: 'You are not part of this classroom' });
        }

        return res.status(200).json({ message: 'Successfully left the classroom' });
    } catch (err) {
        return res.status(500).json({ message: 'Internal server error', error: err });
    }
});

My database Schema is as follows:

classroomModel - classrooms created by teachers stored here
const mongoose = require('mongoose');

const ClassroomSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    owner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',  // Reference to the User model
        required: true
    },
    description: {
        type: String,
        trim: true
    },
    students: [String],
    posts: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Post'
    }]
}, {timestamps: true});

const Classroom = mongoose.model('Classroom', ClassroomSchema);

module.exports = Classroom; 
// classroomJoinModel - Students who join the classroom will be stored here
const mongoose = require('mongoose');

const classroomJoinSchema = new mongoose.Schema({
    classroomId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Classroom',  // Reference to the Classroom model
        required: true
    },
    studentEmail: {
        type: String,
        required: true
    },
    code: {
        type: String,
        required: true
    },
    classOwnerEmail: {
        type: String,
        required: true
    }
}, { timestamps: true });

const ClassroomJoin = mongoose.model('ClassroomJoin', classroomJoinSchema);

module.exports = ClassroomJoin;

In the route I mentioned, I'm getting classroomId but not getting user email. Instead of this if we fetched & delete the object created in ClassroomJoinModel classroom collection will be updated & student will be left.

Console Output:

classroomId:  679bafd26f16f2790e992e3b
email:  undefined

But I'm not understanding how to get data from classroomJoinModel, I need help with this.

I'm building a MERN project i.e. a Teacher's forum application where teachers can create their own classroom & give access to particular students through OTP service. But while I'm building a route for student user which "leave" means under every classroom there is a leave button which when clicked student should leave a classroom.

The code through which you'll get an idea:

// route for leave classroom
router.delete('/leave/:classid', authTokenHandler, async (req, res) => {
    const { classid } = req.params;
    console.log("From classroom: ", classid);
    const userEmail = req.user?.email; // Get the authenticated user's email
    console.log("Email: ", userEmail);
    

    try {
        // Find and delete the student's entry from the classroomJoin collection
        const classroomEntry = await ClassroomJoin.findOneAndDelete({
            classroomId: classid,
            studentEmail: userEmail
        });

        if (!classroomEntry) {
            return res.status(400).json({ message: 'You are not part of this classroom' });
        }

        return res.status(200).json({ message: 'Successfully left the classroom' });
    } catch (err) {
        return res.status(500).json({ message: 'Internal server error', error: err });
    }
});

My database Schema is as follows:

classroomModel - classrooms created by teachers stored here
const mongoose = require('mongoose');

const ClassroomSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        trim: true
    },
    owner: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User',  // Reference to the User model
        required: true
    },
    description: {
        type: String,
        trim: true
    },
    students: [String],
    posts: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Post'
    }]
}, {timestamps: true});

const Classroom = mongoose.model('Classroom', ClassroomSchema);

module.exports = Classroom; 
// classroomJoinModel - Students who join the classroom will be stored here
const mongoose = require('mongoose');

const classroomJoinSchema = new mongoose.Schema({
    classroomId: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Classroom',  // Reference to the Classroom model
        required: true
    },
    studentEmail: {
        type: String,
        required: true
    },
    code: {
        type: String,
        required: true
    },
    classOwnerEmail: {
        type: String,
        required: true
    }
}, { timestamps: true });

const ClassroomJoin = mongoose.model('ClassroomJoin', classroomJoinSchema);

module.exports = ClassroomJoin;

In the route I mentioned, I'm getting classroomId but not getting user email. Instead of this if we fetched & delete the object created in ClassroomJoinModel classroom collection will be updated & student will be left.

Console Output:

classroomId:  679bafd26f16f2790e992e3b
email:  undefined

But I'm not understanding how to get data from classroomJoinModel, I need help with this.

Share Improve this question edited Feb 9 at 18:19 halfer 20.3k19 gold badges109 silver badges202 bronze badges asked Feb 2 at 14:04 Shubham MerguShubham Mergu 31 bronze badge
Add a comment  | 

1 Answer 1

Reset to default 0

Your authTokenHandler should decode the authentication token and set req.user. If it's missing or incorrectly implemented, req.user?.email will be undefined.

const jwt = require('jsonwebtoken');
const User = require('../models/userModel');

const authTokenHandler = async (req, res, next) => {
    const token = req.header('Authorization')?.split(' ')[1]; // Extract token from header

    if (!token) {
        return res.status(401).json({ message: 'Access denied, no token provided' });
    }

    try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        const user = await User.findById(decoded.id).select('-password'); // Fetch user excluding password

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

        req.user = user; // Attach user to request
        next();
    } catch (err) {
        return res.status(401).json({ message: 'Invalid token' });
    }
};

module.exports = authTokenHandler;

Also you can ensure req.user contains the authenticated user's details. If req.user is undefined, debug by logging inside authTokenHandler.

Now, you can fix the route updating the Classroom collection to remove the student from the students array.

router.delete('/leave/:classid', authTokenHandler, async (req, res) => {
    const { classid } = req.params;
    const userEmail = req.user?.email; // Get the authenticated user's email

    if (!userEmail) {
        return res.status(401).json({ message: 'Unauthorized, user email not found' });
    }

    try {
        // Find the student's entry in ClassroomJoin and delete it
        const classroomEntry = await ClassroomJoin.findOneAndDelete({
            classroomId: classid,
            studentEmail: userEmail
        });

        if (!classroomEntry) {
            return res.status(400).json({ message: 'You are not part of this classroom' });
        }

        // Update Classroom model to remove student email from students array
        await Classroom.findByIdAndUpdate(
            classid,
            { $pull: { students: userEmail } },
            { new: true }
        );

        return res.status(200).json({ message: 'Successfully left the classroom' });
    } catch (err) {
        return res.status(500).json({ message: 'Internal server error', error: err });
    }
});

My authtokenHandler in code! can you help me with this?

const jwt = require("jsonwebtoken");

function checkAuth(req, res, next) {
  const authToken = req.cookies.authToken;
  const refreshToken = req.cookies.refreshToken;

  if (!authToken || !refreshToken) {
    return res.status(401).json({ message: "Unauthorized" });
  }

  jwt.verify(authToken, process.env.JWT_SECRET_KEY, (err, decoded) => {
    if (!err) {
      req.userId = decoded.userId;
      req.ok = true;
      req.message = "Authentication successful";
      next();
    } else {
      jwt.verify(
        refreshToken,
        process.env.JWT_REFRESH_SECRET_KEY,
        (refreshErr, refreshDecoded) => {
          if (refreshErr) {
            return res.status(401).json({ message: "Unauthorized" });
          }

          const newAuthToken = jwt.sign(
            { userId: refreshDecoded.userId },
            process.env.JWT_SECRET_KEY,
            { expiresIn: "1d" }
          );
          const newRefreshToken = jwt.sign(
            { userId: refreshDecoded.userId },
            process.env.JWT_REFRESH_SECRET_KEY,
            { expiresIn: "10d" }
          );

          res.cookie("authToken", newAuthToken, {
            sameSite: "none",
            httpOnly: true,
            secure: true,
          });
          res.cookie("refreshToken", newRefreshToken, {
            sameSite: "none",
            httpOnly: true,
            secure: true,
          });

          req.userId = refreshDecoded.userId;
          req.ok = true;
          req.message = "Authentication successful";
          next();
        }
      );
    }
  });
}

module.exports = checkAuth;
发布评论

评论列表(0)

  1. 暂无评论