Newbie here. I'm trying to create a movie recommendation app and I've been struggling with this authorization problem for a while now. My goal is to have a single user schema with a Boolean 'isAdmin' property to differentiate between ordinary users and admin users. The problem is that when I attempt to query the isAdmin variable in the mutation to ensure that the logged in user passed in from the context has the necessary privileges to perform the operation, I get undefined.
User Schema
const userSchema = new mongoose.Schema({
username: {
type: String,
index: {
unique: true
}
},
email: {
type: String,
required: true,
index: {
unique: true
}
},
password: {
type: String,
required: true
},
contributions: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Movie'
},
isAdmin: {
type: Boolean,
required: true,
default: false
}
})
newMovie mutation
newMovie: async (parent, args, { models, user }) => {
if (!user){
throw new AuthenticationError('You must be signed in to submit a new movie')
}
console.log(user.isAdmin)
if (user && user.isAdmin === false) {
throw new ForbiddenError('You are not qualified')
}
return await models.Movie.create({
title: args.title,
year: args.year,
addedBy: mongoose.Types.ObjectId(user.id)
})
}
I attempted to console log user.isAdmin to see the value but instead I'm getting undefined. I have also tried using enum values 'user and admin' for a property 'roles' with the same result.
CodePudding user response:
After struggling for hours, I realized that loading the user from the context returns an object with only the ObjectId and iat which I believe is the object's date of creation. To access the rest of the properties of the context user, I had to search for the user in models and assign that to a variable from which I can access the rest of the properties.
newMovie: async (parent, args, { models, user }) => {
if(!user){
throw new AuthenticationError('You must be logged in')
}
active = await models.User.findById(user.id)
if(active && active.role !== "ADMIN"){
throw new ForbiddenError('Only users can leave reviews')
}
return await models.Movie.create({
title: args.title,
year: args.year,
addedBy: mongoose.Types.ObjectId(active.id)
})
This was the working solution for this problem.