To authenticate some data kept in other collection (something like refrencing another model) - passport.js

While making toDoList using mongoose and passport I want to authorize the toDoList of user so that other user can't see any others toDoList.
const itemSchema = {
name: String,
}
};
const listSchema = {
items: [itemSchema],
};
const userSchema = new mongoose.Schema({
userName: String,
password: String,
userList: {
type: mongoose.Schema.Types.ObjectId,
ref: 'List'
}
});
I am new in mongoose and authentication can any help me out?

Related

How should I access/modify nested mogoose schema?

I'm not sure how to approach accessing/modifying nested schemas in mongoDB. I have a User schema which has standard info about the user, this also contains a schema for Pages which is a way to organize a user's Bookmarks. I'm developing a backend API that would allow the user to delete a specific bookmark on the page their currently on.
I have a set of mongoose Schema as follows:
user.model.js
const mongoose = require('mongoose');
const Bookmark = new mongoose.Schema({
url: {type: String, required: true, unique: true},
image: {type: String},
title: {type: String},
description: {type: String},
tags: [String],
});
const Page = new mongoose.Schema({
name: {type: String, required: true, unique: true},
image: {type: String},
bookmarks: [Bookmark],
});
const User = new mongoose.Schema({
email: {type: String, required: true, unique: true },
password: {type: String, required: true},
pages: [Page],
},
{collection: 'user-data'}
);
const model = mongoose.model('Userdata', User);
module.exports = model;
I need to build a backend that would remove a specified Bookmark from the current User. Can I simply use findbyIDandRemove()?
index.js
const express = require("express");
const mongoose = require("mongoose");
const jwt = require("jsonwebtoken");
const User = require("./models/user.model");
const app = express();
app.post("/api/remove_bookmark", async (res, req) => {
const token = req.headers["x-access-token"];
try{
const decoded = jwt.verify(token, secret);
const email = decoded.email;
const bookmark = req.body.bookmark;
const user = await User.findOne({email: email});
if(user)
{
await User.findByIdAndRemove(bookmark._id);
}
} catch (err) {
return res.json({status: "error", error: "invalid token"});
}
});
Any help or articles that would pertain to understanding nested schemas would be greatly appreciated.

how to return the user email

I have created post route to store posts in the database. It's a protected route so user can store post only after entering the login details. When I post in postman, I've seen that the user email is not returned in the object. Even in the mongodb collection, I don't see the email associated with the post. How do I include the email as well with the post object. I don't want the user to enter the email again and again when posting because they have already logged in. So I kinda want to store the email automatically with the post. Hope I make sense. Can someone help me with this?
Right now the object is kinda stored like this in the posts collection in mongodb
_id: ObjectId("5f1a99d3ea3ac2afe5"),
text: "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. ",
user:ObjectId("5f1a99d3eac2c82afe5"),
age:20,
country:"India",
gender:"male",
date:2020-07-24T08:23:35.349+00:00,
__v:0
I want the email too in the above object.
Post model
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const PostSchema = new Schema ({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
text: {
type: String,
required: true
},
name: {
type: String
},
email: {
type: String
}
,
age: {
type: Number,
required: true
},
gender: {
type: String,
required: true
},
country: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
})
module.exports = Post = mongoose.model('post', PostSchema)
post route
const express = require('express');
const router = express.Router();
const auth = require('../../middleware/auth')
const { check, validationResult} = require('express-validator');
const User = require('../../models/User')
const Post = require('../../models/Post')
router.post('/', [auth, [
check('text', 'Text is required').not().isEmpty()
]], async (req,res)=>{
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()})
}
try {
const user = await (await User.findById(req.user.id)).isSelected('-password')
const newPost = new Post({
text: req.body.text,
name: user.name,
user: req.user.id,
age: req.body.age,
country: req.body.country,
gender: req.body.gender,
email: req.user.email // this email is not stored with the post and I want this to be automatically posted in the collection without the user having to type it again to save the post
})
const post = await newPost.save();
res.json(post);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error')
}
})
module.exports = router;
User model
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
})
module.exports = User = mongoose.model('user', UserSchema);
Change isSelected to select
const user = await (await User.findById(req.user.id)).isSelected(password')
What I potentially see the problem here is, once you have grabed the object of user, you're still referring to req.user.email instead of user.email.
If that does not solve your problem, try to console.log the user returned from after User.findById
Update:
You can see here that isSelected returns boolean. So you're essentialy getting true for having password field in user. Also instead of req.user.email use user.email

mongoose-unique-validator ReferenceError: User is not defined

I'm new to Node.js so I can't understand what I need to add, to make the default example from mongoose-unique-validator work. Here it is:
const mongoose = require('mongoose'),
uniqueValidator = require('mongoose-unique-validator'),
userSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
room: { type: String, required: true },
});
userSchema.plugin(uniqueValidator);
const user = new User({ username: 'JohnSmith', room: 'asd');
user.save(function (err) {
console.log(err);
});
The part with the user is not working, because of ReferenceError: User is not defined.
As far as I understand, the user part is the part that the library user should define, but I don't know what should be in there to make it work.
TL; DR:
I just want to make an example work.
Thanks.
Update:
Ok, so I've added this line of code:
const User = mongoose.model('Model', userSchema);
and it does not trows an error anymore. But it does not notify that username is not unique. It does not work yet. I want to check a valid username for the room. And that's all.
you didn't define your model collection ("USER") try this:
const mongoose = require('mongoose'),
uniqueValidator = require('mongoose-unique-validator'),
userSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
room: { type: String, required: true },
});
userSchema.plugin(uniqueValidator);
module.exports.User = mongoose.model('User', UserSchema);
then :
const user = new User({ username: 'JohnSmith', room: 'asd');
user.save(function (err) {
console.log(err);
})

Mongoose Populate not populating the data

The following are two blocks of code, the first one is my Schema and the second one is my query. The Payment model is getting saved and it has the id referring to the user. Can I know where I am going wrong, is there any thing wrong with the fundamental ?
Here is my schema of User and Payment
User:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
var paymentSchema = new Schema({
amount: Number,
user: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
var userSchema = new Schema({
email: String,
payment: {
type: Schema.Types.ObjectId,
ref: 'Payment'
}
});
module.exports = mongoose.model('User', userSchema);
module.exports = mongoose.model('Payment', paymentSchema);
Here is my query which I am using to populate using promise:
User.findOne({email: req.query.email})
.populate('payment')
.select('_id payment')
.then(function(user) {
res.json(user);
});

populate embedded document on mongoose nodejs

I'm currently working with nodeJs and mongoose and I want to populate a sub-document
This is my main model
var postSchema = require('./post.js');
var blogSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
postSchema: [postSchema]
});
var blog = mongoose.model('blog', blogSchema);
module.exports = blog;
this is the post sub-document
var mongoose = require('mongoose');
var postSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
rol: {
type: String,
required: true
}
});
var post = mongoose.model('post', post);
module.exports = post;
And I want to add several 'post' inside the 'blog' schema, but I don't know how, I tried populating it by I'm now doing it properly! I read about 'populate' on mongoose but I'm not understanding it at all, can someone explain it?
You cannot use arrays of external Eschemas in mongoose. You must define them in the same file, or just save the array of _id´s and create a collection appart.
Check the mongoose docs. They talk about that: http://mongoosejs.com/docs/2.7.x/docs/embedded-documents.html
var mongoose = require('mongoose');
var blogPost = new mongoose.Schema({
name: {
type: String,
required: true
},
rol: {
type: String,
required: true
}
});
var blog = new mongoose.Schema({
name: {
type: String,
required: true
},
postList: [blogPost]
});
mongoose.model('blog', blogSchema);
module.exports = blog;
var Blog = mongoose.model('blog');
// create a blog post
var theBlog = new Blog();
// create a comment
theBlog.postList.push({ title: 'My comment' });
theBlog.postList.save(function (err) {
if (!err) console.log('Success!');
});
Hope it may help you

Resources