I want to do this in Node.JS
I want to have a link like this, it should be a GET Request
http://localhost:3000/api/bal/update-balance?email=aa#email.com&amount=4500
How can I do this in Node.JS
My code is looking Thus
const router = require("express").Router();
const User = require("../models/User");
const Trans = require("../models/Transactions");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
router.post("/update-balance", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const amount = parseInt(req.body.amount);
const user = await User.find({ email: req.body.email });
const balance = parseInt(user[0].balance);
//return balance;
//console.log(balance);
const total_amt = amount + balance;
//console.log(total_amt);
// update Balance
//const wallet_user = new User();
try{
await User.findOneAndUpdate({email : req.body.email}, {$set: {balance: total_amt}});
const transactions = new Trans({
email: req.body.email,
narration: 'NEW DEPOSIT - '+amount,
credit: amount,
debit: 0.00,
amount: amount,
});
transactions.save();
}catch(err){
console.log(err);
}
return res.send({ error: false, message: "OK" });
} catch (error) {
res.status(404).json({ message: error.message });
}
});
module.exports = router;
Please See above Code.
router.get(("/update-balance"), async( req,res) => {
try {
const amount = req.query.amount;
const email = req.query.email;
//you can do the rest of the work here
}
catch (error) {
res.status(500).json({ message: error.message })
}
})
Related
I'm trying to get all my users from MongoDB, I've readed all documentations, but nothing helps.. What I'm trying to do is set my back-end mainController and create a get request which helps me get all users in front, so I can display them in my page. I'm still learning how to work with MongoDB, so sorry for my awful question.
mainController:
const uid = require('uid-safe')
const bcrypt = require('bcrypt')
const UserSchema = require('../schemas/UserSchema');
const { db } = require('../schemas/UserSchema');
const { default: mongoose } = require('mongoose');
module.exports = {
register: async (req, res) => {
const { username, email, password, image, city, country, firstName, lastName, phone, gender, birth } = req.body;
const userExists = await UserSchema.findOne({ username });
if (userExists) {
return res.send({ error: true, message: 'User with this username exists', data: null });
}
const emailExists = await UserSchema.findOne({ email });
if (emailExists) {
return res.send({ error: true, message: 'User with this email exists', data: null });
}
const id = await uid(7);
const hashedPass = await bcrypt.hash(password, 3);
const user = new UserSchema({
secret: id,
username,
email,
password: hashedPass,
image,
city,
country,
firstName,
lastName,
phone,
gender,
birth
});
await user.save();
return res.send({ error: false, message: 'User successfully registrated!', data: null });
},
login: async (req, res) => {
const { username, password } = req.body;
const loginUser = await UserSchema.findOne({ username });
if (loginUser) {
const passMatch = bcrypt.compare(password, loginUser.password)
if (passMatch) {
return res.send({ error: false, message: `Welcome back ${username}!`, data: loginUser })
}
return res.send({ error: true, message: 'Invalid password', data: null });
};
return res.send({ error: true, message: 'Invalid username', data: null });
},
getSingleUser: async (req, res) => {
const { secret } = req.params;
const findUser = await UserSchema.findOne({ secret });
if (findUser) {
return res.send({ error: false, message: 'User found', data: findUser });
}
return res.send({ error: true, message: 'User not found', data: null });
},
updateUser: async (req, res) => {
try {
const updateduser = await User.updateOne({ secret: req.params.secret }, { $set: req.body });
res.status(200).json(updateduser);
} catch (error) {
res.status(400).json({ message: error.message });
}
}
};
mainRouter:
const express = require('express')
const { login, register, getSingleUser, authSession, usersApi } = require("../controller/mainController")
const { loginValidate, registerValidate } = require("../middleware/authValidator")
const mainRouter = express.Router()
mainRouter.post('/register', registerValidate, register);
mainRouter.post('/login', loginValidate, login);
mainRouter.get('/user/:secret', getSingleUser)
module.exports = mainRouter;
Thank you!
I think you can use the find function.
const uid = require('uid-safe')
const bcrypt = require('bcrypt')
const UserSchema = require('../schemas/UserSchema');
const { db } = require('../schemas/UserSchema');
const { default: mongoose } = require('mongoose');
module.exports = {
register: async (req, res) => {
const { username, email, password, image, city, country, firstName, lastName, phone, gender, birth } = req.body;
const userExists = await UserSchema.findOne({ username });
if (userExists) {
return res.send({ error: true, message: 'User with this username exists', data: null });
}
const emailExists = await UserSchema.findOne({ email });
if (emailExists) {
return res.send({ error: true, message: 'User with this email exists', data: null });
}
const id = await uid(7);
const hashedPass = await bcrypt.hash(password, 3);
const user = new UserSchema({
secret: id,
username,
email,
password: hashedPass,
image,
city,
country,
firstName,
lastName,
phone,
gender,
birth
});
await user.save();
return res.send({ error: false, message: 'User successfully registrated!', data: null });
},
login: async (req, res) => {
const { username, password } = req.body;
const loginUser = await UserSchema.findOne({ username });
if (loginUser) {
const passMatch = bcrypt.compare(password, loginUser.password)
if (passMatch) {
return res.send({ error: false, message: `Welcome back ${username}!`, data: loginUser })
}
return res.send({ error: true, message: 'Invalid password', data: null });
};
return res.send({ error: true, message: 'Invalid username', data: null });
},
getSingleUser: async (req, res) => {
const { secret } = req.params;
const findUser = await UserSchema.findOne({ secret });
if (findUser) {
return res.send({ error: false, message: 'User found', data: findUser });
}
return res.send({ error: true, message: 'User not found', data: null });
},
updateUser: async (req, res) => {
try {
const updateduser = await User.updateOne({ secret: req.params.secret }, { $set: req.body });
res.status(200).json(updateduser);
} catch (error) {
res.status(400).json({ message: error.message });
}
},
getAllUsers: async(req, res) => {
try {
const allUser = await User.find({});
res.status(200).json(allUser);
} catch (error) {
res.status(400).json({ message: error.message });
}
}
};
const express = require('express')
const { login, register, getSingleUser, authSession, usersApi, getAllUsers } = require("../controller/mainController")
const { loginValidate, registerValidate } = require("../middleware/authValidator")
const mainRouter = express.Router()
mainRouter.post('/register', registerValidate, register);
mainRouter.post('/login', loginValidate, login);
mainRouter.get('/user/all', getAllUsers);
mainRouter.get('/user/:secret', getSingleUser);
module.exports = mainRouter;
i have this code i am trying to write, the code is supposed to update the balance in MongoDB after properly computing the balance. The challenge is , it does not, it properly computes the balance, but updating the column for the user, it does not update. Looking out to see where and how to update the balances only I have not seen anything to help.
My code is Looking thus :
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
router.post("/update-balance/:email", async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith("Bearer ") ||
!req.headers.authorization.split(" ")[1]
) {
return res.status(422).json({ message: "Please Provide Token!" });
}
const amount = parseInt(req.body.amount);
const user = await User.find({ email: req.params.email });
const balance = parseInt(user[0].balance);
//return balance;
//console.log(balance);
const total_amt = amount + balance;
//console.log(total_amt);
// update Balance
const wallet_user = new User();
try{
await wallet_user.updateOne({email : req.params.email}, {$set: {balance: total_amt}});
}catch(err){
console.log(err);
}
return res.send({ error: false, message: "OK" });
} catch (error) {
res.status(404).json({ message: error.message });
}
});
module.exports = router;
What Am I suppose to do that i am not doing rightly, kindly help.
The code above shows What I have attempted..
You can use $inc:
router.post('/update-balance/:email', async (req, res) => {
try {
if (
!req.headers.authorization ||
!req.headers.authorization.startsWith('Bearer ') ||
!req.headers.authorization.split(' ')[1]
) {
return res.status(422).json({ message: 'Please Provide Token!' });
}
const amount = parseInt(req.body.amount);
try {
await User.findOneAndUpdate(
{ email: req.params.email },
{ $inc: { balance: amount } }
);
} catch (err) {
console.log(err);
}
return res.send({ error: false, message: 'OK' });
} catch (error) {
res.status(404).json({ message: error.message });
}
});
I have created a middleware folder inside it I have created fetchuser.js
This is my fetchuser.js code, I have created getuser endpoint so that I can authenticate the user.
I have created a new post request in my thunderclient, but because of this error I am not able to do anything
...
const jwt = require('jsonwebtoken');
const JWT_SECRET = "Saurabhisgood$ouy";
const fetchuser = (req, res, next) => {
// Get the user from jwt token and id to req object
const token = req.header('auth-token');
if (!token) {
res.status(401).send({ error: "Please authenticate using a valid token" })
}
try {
const data = jwt.verify(token, JWT_SECRET)
req.user = data.user;
next();
} catch (error) {
res.status(401).send({ error: "Please authenticate using a valid token" })
}
}
module.exports = fetchuser();
...
This is auth.js file
...
const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs');
const JWT_SECRET = "Saurabhisgood$ouy";
const jwt = require('jsonwebtoken');
const fetchuser = require('../middleware/fetchuser');
// Create a user using : POST "/api/auth/createuser". Doesn't require auth. Dosen't require login
router.post('/createuser', [
body('name', 'Name should be atleast 3 characters').isLength({ min: 3 }),
body('email', 'Email should be unique').isEmail(),
body('password', 'Password must be atleast 5 characters').isLength({ min: 5 }),
], async (req, res) => {
// If there are errors then you will get bad request
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Check whether the user with the same email exists
try {
let user = await User.findOne({ email: req.body.email });
if (user) {
return res.status(400).json({ error: "The user with this email already exists" })
}
const salt = await bcrypt.genSalt(10);
const secPass = await bcrypt.hash(req.body.password, salt);
// Create a new user
user = await User.create({
name: req.body.name,
email: req.body.email,
password: secPass
});
const data = {
user: {
id: user.id
}
}
const authToken = jwt.sign(data, JWT_SECRET);
// console.log(jwtData);
// res.json(user);
res.json({authToken});
} catch (error) {
console.error(error.message);
res.status(500).send("Internal server error")
}
})
// Authenticate a user using : POST "/api/auth/login". Doesn't require auth. Dosen't require login
router.post('/login', [
body('email', 'Email should be unique').isEmail(),
body('password', 'Password cannot be blank').exists(),
], async (req, res) => {
// If there are errors then you will get bad request
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
};
const { email, password } = req.body;
// Check whether the user with the same email exists
try {
let user = await User.findOne({email});
if (!user) {
return res.status(400).json({ error: "Please enter the valid credentials" })
}
const passwordComapare= await bcrypt.compare(password, user.password);
if (!passwordComapare) {
return res.status(400).json({ error: "Please enter the valid credentials" })
}
const data = {
user: {
id: user.id
}
}
const authToken = jwt.sign(data, JWT_SECRET);
// console.log(jwtData);
// res.json(user);
res.json({authToken});
} catch (error) {
console.error(error.message);
res.status(500).send("Internal server error")
}
})
// Get details of logged in user using : POST "/api/auth/getuser". Require login
router.post('/getuser', fetchuser , async (req, res) => {
try {
userId= req.user.id;
const user= await User.findById(userId).select("-password");
res.send(user);
} catch (error) {
console.error(error.message);
res.status(500).send("Internal server error")
}
})
module.exports = router
...
You invoking the middleware automatically, change:
module.exports = fetchuser();
to:
module.exports = fetchuser;
I got these errores when I try to post the http://localhost:5000/user/login url with postman
Error: Illegal arguments: string, undefined
at _async (C:\Users\Raghava\Desktop\react_vite\server\node_modules\bcryptjs\dist\bcrypt.js:286:46)
at C:\Users\Raghava\Desktop\react_vite\server\node_modules\bcryptjs\dist\bcrypt.js:307:17
at new Promise ()
at Object.bcrypt.compare (C:\Users\Raghava\Desktop\react_vite\server\node_modules\bcryptjs\dist\bcrypt.js:306:20) at C:\Users\Raghava\Desktop\react_vite\server\router\UserRouter.js:106:34
at processTicksAndRejections (internal/process/task_queues.js:93:5)
server.js
const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const authroute = require("./router/UserRouter");
//config the express
const app = express();
//config the cors
app.use(cors());
//config the body-parser
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//config the .env
dotenv.config({ path: "./config/config.env" });
//port
const port = 5000;
//connect to database
mongoose
.connect(process.env.MONGO_DB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => console.log("connected to database successfully..."))
.catch((err) => console.log(err));
//config the routes
app.use("/user", authroute);
//starting the server
app.listen(port, () => {
console.log(`server is started at posrt ${port}`);
});
userRouter.js
const express = require("express");
const Router = express.Router();
const User = require("../models/User");
const bcrypt = require("bcryptjs");
const gravatar = require("gravatar");
const jwt = require("jsonwebtoken");
const { check, validationResult } = require("express-validator/check");
Router.post(
"/register",
[
check("name").notEmpty().withMessage("name is required"),
check("email").isEmail().withMessage("proper email is required"),
check("password")
.isLength({ min: 6 })
.withMessage("min 6 chars for password"),
],
async (req, res) => {
let errors = validationResult(req);
//if error containes
if (!errors.isEmpty()) {
return res.status(400).json({
errors: errors.array(),
});
}
try {
let { name, email, password } = req.body;
//user exist
let user = await User.findOne({ email });
if (user) {
return res.status(400).json({
errors: [{ msg: "user alredy exist" }],
});
}
//encrypt the password
let salt = await bcrypt.genSalt(10);
password = await bcrypt.hash(password, salt);
//get the avatar
let avatar = gravatar.url(email, {
s: "200",
r: "pg",
});
//store the user
user = new User({ name, email, password, avatar });
await user.save();
//json web token
let payload = {
user: {
id: user.id,
},
};
jwt.sign(payload, process.env.JWT_SECRET_KEY, (err, token) => {
if (err) {
throw err;
}
res.status(200).json({
result: "success",
token: token,
});
});
} catch (error) {
console.error(error);
res.status(500).json({
errors: [{ msg: error.message }],
});
}
}
);
Router.post(
"/login",
[
check("email").isEmail().withMessage("proper email is required"),
check("password").notEmpty().withMessage("password is required"),
],
async (req, res) => {
let errors = validationResult(req);
//if error containes
if (!errors.isEmpty()) {
return res.status(400).json({
errors: errors.array(),
});
}
try {
let { email, password } = req.body;
//check for email
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ errors: [{ msg: "invalid credentials" }] });
}
//compare password
let isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ errors: [{ msg: "invalid credentials" }] });
}
//json web token
let payload = {
user: {
id: user.id,
},
};
jwt.sign(payload, process.env.JWT_SECRET_KEY, (err, token) => {
if (err) {
throw err;
}
res.status(200).json({
result: "success",
token: token,
});
});
} catch (error) {
console.error(error);
res.status(500).json({
errors: [{ msg: error.message }],
});
}
}
);
module.exports = Router;
It's most likely throwing and error because your code does not return after you check if the user exists:
let user = await User.findOne({ email });
if (!user) {
res.status(400).json({ errors: [{ msg: "invalid credentials" }] });
// most likely still runs code after this because it is not returning.
}
Please add the return keyword before res.status(400).json({ errors: [{ msg: "invalid credentials" }] }).
Final Code:
if (!user) {
return res.status(400).json({ errors: [{ msg: "invalid credentials" }] });
}
Additionally, I looked over your code before the error. You do await bcrypt.genSalt(10) and await bcrypt.hash(password, salt). If you take a look at the documentation, you need to passing in a callback for the async version. If you want to use the sync version and not use a callback, please do, bcrypt.genSaltSync() and bcrypt.hashSync().
What I'm trying to do here is use the 2 functions but I don't know how to use both of them as they're both post functions with same name and I want to able to test using postman. These are in the same file
const jwt = require('jsonwebtoken');
const Joi = require('joi');
const bcrypt = require('bcrypt');
const _ = require('lodash');
const { users } = require('../models/user');
const express = require('express');
const router = express.Router();
this is the first post function
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
let user = await users.findOne({ email: req.body.email });
if (!user) {
return res.status(400).send('Incorrect email or password.');
}
const validPassword = await bcrypt.compare(req.body.password,
user.password);
if (!validPassword) {
return res.status(400).send('Incorrect email or password.');
}
const token = jwt.sign({ _id: user._id }, 'PrivateKey');
res.header('x-auth-token', token).send(_.pick(user, ['_id', 'name',
'email']));
});
this is the second post function
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
let user = await users.findOne({ email: req.body.email });
if (!user) {
return res.status(400).send('Incorrect email or password.');
}
const validPassword = await bcrypt.compare(req.body.password,
user.password);
if (!validPassword) {
return res.status(400).send('Incorrect email or password.');
}
});
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);
}
and lastly the last line in the file
module.exports = router;
You cannot have 2 handlers for same REST endpoint with same METHOD. Why don't you change one to router.post('/login')