How do I put one instance of a mongodb item into another? - javascript

I am trying to put a book into a user, as the user can borrow books. I don't have any idea how to do this, so I was hoping someone could help me. I have code for the routes of books and users.
//users
const express = require("express");
const router = express.Router();
const User = require('../models/user');
router.get("/",async(req,res)=>{
try{
const users = await User.find();
res.json(users);
}catch (err){
res.send(err);
}
});
router.post('/', async(req,res)=>{
const user = new User({
id: req.body.id,
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
borrowed_books: req.body.borrowed_books,
password: req.body.password
});
try {
const us = await user.save();
res.json(us);
}catch (err){
console.error(err);
}
});
module.exports = router;
//books
const express = require("express");
const router = express.Router();
const Book = require('../models/book');
router.get("/", async(req,res)=>{
try {
const books = await Book.find();
res.json(books);
} catch (err){
console.error(err);
}
});
router.post("/", async(req,res)=>{
const book = new Book({
Text: req.body.Text,
Type: req.body.Type,
Issued: req.body.Issued,
Title: req.body.Title,
Language: req.body.Language,
Authors: req.body.Authors,
Subjects: req.body.Subjects,
Bookshelves: req.body.Bookshelves
});
try {
const bo = await book.save();
res.json(bo);
}catch (err){
console.error(err);
}
});
module.exports = router;
//server.js
const express = require("express");
const mongoose = require("mongoose");
const app = express();
mongoose.default.connect("mongodb://localhost/database",{},(err)=>{
console.error(err);
});
const usersRouter = require('./routes/users')
const booksRouter = require('./routes/books')
const con = mongoose.default.connection;
con.on('open',function(){
console.log("connected...");
});
app.use(express.json());
app.use("/api/users",usersRouter);
app.use("/api/books",booksRouter);
app.listen(9000,function(){
console.log("server started");
});
Thanks
I tried using express.router().put() but I have no idea how to use it and how I would allow users to put books from the book database into their own borrowed_books attribute.

Related

I don't want to login if I already login in node js

Everything is going great which I shared code but the problem is that when I log in the next time when I visit the website it shows me again the login form so I don't want this process repeatedly
I used there bcrypt,jwt token and cookies for user login
This is my route where I define user register and login
router.post("/api/usersave", urlencodedParser, vUserController.createUser)
router.post("/api/userlogin", urlencodedParser, vUserController.loginUser)
This is my controller of user registration and login
const express = require("express");
const app = express();
const path = require("path")
var bodyParser = require('body-parser')
const mongoose = require("mongoose")
const hbs = require('hbs');
const router = express.Router()
const bcrypt = require("bcrypt")
const jwt = require("jsonwebtoken")
const cookieparser = require("cookie-parser")
exports.createUser=(req, res)=>{
// console.log(req.body.itemname)
const oldUser = userModel.findOne({ username: req.body.username });
if (oldUser) {
return res.status(409).send("User Already Exist. Please Login");
}
const rsUsers = new userModel(req.body)
rsUsers.save().then(() => {
console.log('User: ' + req.body.username + ' Saved')
}).catch((err)=>{
console.log('User Saved Error..' + err)
});
res.render("home", {abc: req.body})
// res.send("User Created ... ")
return true
}
exports.loginUser= async (req, res)=>{
// console.log(req.body.username)
// console.log(password)
var password = req.body.password
const findUser = await userModel.findOne({username: req.body.username})
// console.log(findUser.username)
if (!findUser){
res.send("User ID Not Found")
}
else {
bcrypt.compare(req.body.password, findUser.password, function(err, result) {
if (!result){
// console.log('User Login Failed')
res.send("User Login Failed")
}
else{
console.log('User Login Successfully')
const vToken = findUser.generateJWTToken()
res.cookie("node1", vToken)
// console.log(vToken)
res.render("home", {abc: req.body})
}
});
}
}
This is my model of user registration and login
const express = require("express");
const app = express();
const path = require("path")
var bodyParser = require('body-parser')
const mongoose = require("mongoose")
const bcrypt = require('bcrypt')
const jwt = require("jsonwebtoken")
const schema2 = new mongoose.Schema({
username: {type: String, required: true},
useremail: String,
password: String,
tokens: [{
token: String
}]
})
schema2.pre('save', async function(next){
// var saltrange = bcrypt.genSalt(10)
if(this.isModified("password")){
var saltrange = 10
this.password = bcrypt.hashSync(this.password, saltrange)
next()
}
})
schema2.methods.generateJWTToken = function(){
try {
var generatedtoken = jwt.sign({id: this._id}, "FULLSTACKWEBDEVELOPMENTMEANMERNBATCH")
// console.log(generatedtoken)
this.tokens = this.tokens.concat({token: generatedtoken})
this.save()
return generatedtoken
}
catch(err){
console.log(err)
return "false"
}
}
const userModel = mongoose.model('userModel', schema2)
module.exports = userModel
enter code here
You can control this login page rendering by checking you are valid login user or not. You can check this by a middleware function in your route file
const {isLoggedIn} = require("./middleware");
app.get("/login", isLoggedIn, (req, res)=>{
res.render("login");
})
app.get("/reg", isLoggedIn, (req, res)=>{
res.render("userRegister");
})
//For Logout from this session simply hit logout url
router.get('/logout', async (req, res) => {
res.clearCookie('node1')
res.redirect("/login");
});
where isLoggedIn is a middleware function which will check if you are an existing valid user or not
middleware.js
const jwt = require('jsonwebtoken');
module.exports.isLoggedIn = async(req,res, next)=>{
try{
const token = req.cookies ? req.cookies.node1 : null;
const decoded = token ? jwt.verify(token, "FULLSTACKWEBDEVELOPMENTMEANMERNBATCH") : null
if(decoded){
return res.redirect('/home');
}
console.log(decoded);
next();
}catch(err){
res.render("login");
}
}
Hoping this may work in your case

Exporting Multiple Objects Stops My HTML Requests from being processed

I have some simple javascript code in three files. There is my server.js, which has
const userRouter = require('./routes/users')
app.use("/",userRouter)
Then there is my middleware users.js with
module.exports = router
and lastly user.js with
module.exports = {
User:User,
validateLogin:validateUserLogin,
validateRegister:validateUserRegister,
}
When my user.js had just the export line module.exports = User my code worked just fine. server.js imports users.js, which imports user.js. But when exporting functions along with my User object, my requests stop working. Why? How can I fix this? I'm using Node.js with express and mongo db. All my HTML requests are in users.js.
The code to my server.js is
const express = require('express');
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
//just show server is running
const app = express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const PORT = 4000;
app.get("/status", async (req, res) => {
return res.status(400).send("server for GET is running");
});
app.post("/status", async (req, res) => {
return res.status(200).send({
status: "server for POST is running",
message: req.body.message
});
});
app.listen(PORT, function() {
console.log(`server running on port ${PORT}`);
});
const url = "mongodb+srv://Admin:strongpassword#cluster0.tjual.mongodb.net/ConfusedTom?retryWrites=true&w=majority"
mongoose.connect(url, {
useNewUrlParser: true,
useUnifiedTopology: true,
dbName: "ConfusedTom"
}).then(() => {
console.log("connected successfully to server, using database %s\n", mongoose.connection.$dbName);
}).catch(err => {
console.log(err);
});
const userRouter = require('./routes/users')
app.use("/",userRouter)
and here is my users.js
const mongoose = require("mongoose");
const express = require("express");
const router = express.Router();
const ObjectId = mongoose.Types.ObjectId;
const Review = require("../models/review.js")
const TVShow = require("../models/tvshows.js")
const { User, validateLogin, validateRegister} = require("../models/user.js")
router.get("/username", async (req, res) => {
console.log("reached!")
var user = await User.findOne({ username: req.body.username });
if (!user) return res.status(400).send("User doesn't exist.");
return res.status(200).send(user)
});
router.post("/register", async(req,res) => {
const { error } = validateRegister(req.body);
if (error) return res.status(400).send(error.details[0].message);
else user = await User.findOne({ username: req.body.username });
if (user) return res.status(400).send("Username already taken.");
//create new user
user = new User({
firstName: req.body.firstName,
lastName: req.body.lastName,
username: req.body.username,
password: req.body.password,
});
user.save();
return res.status(200).send("User registered successfully.");
})
router.post("/login", async (req, res) => {
console.log("reached!")
// validate the request body first
const { error } = validateLogin(req.body);
if (error) return res.status(400).send(error.details[0].message);
//find an existing user
var user = await User.findOne({ username: req.body.username });
if (!user) return res.status(400).send("Username reqired.");
if (user) {
if (user.validatePassword(req.body.password)) {
return res.header.status(200).send("User login successfully");
}
else return res.status(400).send("Password is incorrect");
} else return res.status(400).send("User doesn't exist.");
});
module.exports = router
The problem with your updated import of the stuff from user.js is you're using the wrong names for the functions. You currently have:
const UserStuff = require("../models/user.js")
const User = UserStuff.User;
const validateLogin = UserStuff.validateUserLogin;
const validateregister = UserStuff.validateUserRegister;
but the object you're exporting is:
module.exports = {
User:User,
validateLogin:validateUserLogin,
validateRegister:validateUserRegister,
}
You're using the wrong names of the functions (validateUserLogin instead of validateLogin). The names you use have to match at both ends. So:
const UserStuff = require("../models/user.js")
const User = UserStuff.User;
const validateLogin = UserStuff.validateLogin;
// ^^^^^^^^^^^^^
const validateregister = UserStuff.validateRegister;
// ^^^^^^^^^^^^^^^^
or more concisely:
const { User, validateLogin, validateRegister} = require("../models/user.js")

my template engine file not rendered in my router file

hello every one in this code i have a template engine file but not rendered and i havent a error
and i cant see it
i need a help in /admin/article/new
this is my module code
const express = require('express');
const router = express.Router()
const Article = require('../models/article')
const User = require('./../models/users');
router.post('/signup', async(req, res, next) => {
req.user = new User()
next()
}, saveing());
function saveing() {
return async(req, res) => {
let user = req.user
user.username = req.body.username
user.password = req.body.password
try {
user = await user.save()
res.send("ok saves")
// res.render('article/new')
} catch (e) {
res.send("40004")
console.log(e)
console.log("error==============")
}
}
}
router.post('/signin', async(req, res) => {
const user = await User.findOne({
username: req.body.username,
password: req.body.password
})
if (user) {
res.render('/admin/article/new', { article: new Article() })
} else {
res.send("400404040")
}
})
module.exports = router;
sorry for my bad english

Postman returns ' Could not get any response '

Postman returns ' Could not get any response ' when I send a Post request, but get a request to other URL works just fine. please how can I resolve this issue? index.js is the entry point to my application. the get URL below is working.
index.js
const express = require('express')
const mongoose = require('mongoose')
const dotenv = require('dotenv')
const bodyParser = require('body-parser')
const app= express()
//body parser
app.use(bodyParser.json())
//config
dotenv.config()
//connect to db
mongoose.connect(
process.env.DB_CONNECTION,
{ useNewUrlParser: true },
()=>{
console.log('contented to db')
}
)
//import route
const authRoute = require('./ROUTES/auth')
app.use('', authRoute)
app.use('/api/user', authRoute)
//start server
app.listen(5000);
# auth.js #
all routings are done in auth.js
const express =require('express')
const router = express.Router();
const User = require('./moduls/User')
router.get('/',(req, res)=>{
res.send('home')
})
//validation schema
const joi =require('#hapi/joi');
const regSchema ={
name:joi.string().min(6).required(),
email:joi.string().required().email(),
password:joi.string().min(8).required()
}
router.post('/register', async(req, res)=>{
//check and return error status
const { error } = joi.ValidationError(regSchema);
if(error) return res.status(400).json({message: err})
const emailExist = await User.findOne(req.body.email)
if (emailExist) return res.status(400).json({message:'there is a user with this email'})
//get user object
const user =new User({
name:req.body.name,
email:req.body.email,
password:req.body.password,
rePassword:req.body.rePassword
})
try{
await user.save()
.then(data=>{
res.json(data)
})
}
catch(err){
res.status(400).json({message: err})
}
})
module.exports=router;
modules/User.js
user module in the modules folder
const mongoose = require('mongoose')
const userSchema =new mongoose.Schema({
name:{
type: String,
required:true,
min:6,
max:30
},
email:{
type: String,
required:true,
max:100
},
password:{
type:String,
required:true,
min:8
},
rePassword:{
type:String,
required:true,
min:8
},
date:{
type:Date,
default:Date.now()
}
})
module.exports = mongoose.model('User', userSchema)
The .save() function returns a promise that you can await. You don't need to use .then() when using async/await.
Instead of this.
await user.save()
.then(data=>{
res.json(data)
})
I'd do this.
const data = await user.save();
res.json(data);

Getting error: FATAL ERROR: jwtPrivateKey is not defined.'

I'm still having some exception errors about JSON web token Private Key. It says it's not defined but I think I already put the JSON web token private key and still throwing an error. I'm not sure where the problem is maybe in the user module or auth module or on the config. Please see the below code and any help would be appreciated.
//default.json
{
"jwtPrivateKey": "",
"db": "mongodb://localhost/vidly"
}
// test.json
{
"jwtPrivateKey": "1234",
"db": "mongodb://localhost/vidly_tests"
}
// config.js
const config = require('config');
module.exports = function() {
if (!config.get('jwtPrivateKey')) {
throw new Error('FATAL ERROR: jwtPrivateKey is not defined.');
}
}
// users.js
const auth = require('../middleware/auth');
const jwt = require('jsonwebtoken');
const config = require('config');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const {User, validate} = require('../models/user');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.get('/me', auth, async (req, res) => {
const user = await User.findById(req.user._id).select('-password');
res.send(user);
});
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (user) return res.status(400).send('User already registered.');
user = new User(_.pick(req.body, ['name', 'email', 'password']));
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
const token = user.generateAuthToken();
res.header('x-auth-token', token).send(.pick(user, ['id', 'name', 'email']));
});
module.exports = router;
// auth.js
const Joi = require('joi');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const {User} = require('../models/user');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) return res.status(400).send(error.details[0].message);
let user = await User.findOne({ email: req.body.email });
if (!user) return res.status(400).send('Invalid email or password.');
const validPassword = await bcrypt.compare(req.body.password, user.password);
if (!validPassword) return res.status(400).send('Invalid email or password.');
const token = user.generateAuthToken();
res.send(token);
});
function validate(req) {
const schema = {
email: Joi.string().min(5).max(255).required().email(),
password: Joi.string().min(5).max(255).required()
};
return Joi.validate(req, schema);
}
module.exports = router;
// db.js
const winston = require('winston');
const mongoose = require('mongoose');
const config = require('config');
module.exports = function() {
const db = config.get('db');
mongoose.connect(db)
.then(() => winston.info(Connected to ${db}...));
}
// logging.js
const winston = require('winston');
// require('winston-mongodb');
require('express-async-errors');
module.exports = function() {
winston.handleExceptions(
new winston.transports.Console({ colorize: true, prettyPrint: true }),
new winston.transports.File({ filename: 'uncaughtExceptions.log' }));
process.on('unhandledRejection', (ex) => {
throw ex;
});
winston.add(winston.transports.File, { filename: 'logfile.log' });
// winston.add(winston.transports.MongoDB, {
// db: 'mongodb://localhost/vidly',
// level: 'info'
// });
}
// index.js
const winston = require('winston');
const express = require('express');
const app = express();
require('./startup/logging')();
require('./startup/routes')(app);
require('./startup/db')();
require('./startup/config')();
require('./startup/validation')();
const port = process.env.PORT || 3000;
app.listen(port, () => winston.info(Listening on port ${port}...));
// user.test.js
const {User} = require('../../../models/user');
const jwt = require('jsonwebtoken');
const config = require('config');
const mongoose = require('mongoose');
describe('user.generateAuthToken', () => {
it('should return a valid JWT', () => {
const payload = {
_id: new mongoose.Types.ObjectId().toHexString(),
isAdmin: true
};
const user = new User(payload);
const token = user.generateAuthToken();
const decoded = jwt.verify(token, config.get('jwtPrivateKey'));
expect(decoded).toMatchObject(payload);
});
});
// package.json
"scripts": {
"test": "jest --watchAll --verbose"
},
the structure of your config files are wrong. if u check the https://www.npmjs.com/package/config
this is the structure of file:
{
"Customer": {
"dbConfig": {
"host": "prod-db-server"
},
"credit": {
"initialDays": 30
}
}
}
that page also provides this info:
config.get() will throw an exception for undefined keys to help catch typos and missing values. Use config.has() to test if a configuration value is defined.
I think set does not work with visual studio code terminal. I had same issue, when i executed in Windows CMD it worked.
Try config.get instead of config.has()
module.exports = function() {
if (!config.has('jwtPrivateKey')) {
throw new Error('FATAL ERROR: jwtPrivateKey is not defined.');
}
if you are using mosh's tutorial as it said here you should have a file named custom-environment-variables.json too and it contains:
{
"jwtPrivateKey": "vidly_jwtPrivateKey"
}
then you have to set an environment variable called vidly_jwtPrivateKey.
in windows you can run this: set vidly_jwtPrivateKey=mySecureKey on CMD.
Hope it solves the problem :)
n
if(!config.has('jwtPrivateKey')) {
console.error("FATAL ERROR: jwtPrivateKey not defined.")
process.exit(1);
}
try to use config.has() instead of config.get()

Categories

Resources