How to create blockUserTime correctly? - node.js

I have security.controller, security.service and VerificationEntity.
So, in security.controller I have checkVerificationCode method in which I am trying to block the user if he has exceeded the allowed number of inputs of the wrong code and create the timestamp of the last failed attempt, and then in security.service I'm saving this blockedTime into the blockedTime column in VerificationEntity.
Problem is, when I'm trying to check code again during this block time, blockedTime is updating again. How can I prevent it and make blockedTime static, in order to further compare it with the current timestamp.
security.controller:
public checkVerificationCode = async (req: Request, res: Response) => {
try {
const { mobilePhone, verificationCode, id } = req.body;
const dataToCheck = await this.securityService.checkCode(mobilePhone);
if (verificationCode !== dataToCheck.verificationCode || id !== dataToCheck.id) {
const newTries = dataToCheck.tries + 1;
const triesLeft = +process.env.MAX_CODE_TRIES - +newTries;
if (triesLeft <= 0) {
const blockedTime = await this.securityService.updateBlockTime(mobilePhone, id);
if (timeDiffInMinutes(blockedTime) <= +process.env.USER_BLOCK_EXPIRATION) {
return res.status(StatusCodes.BAD_REQUEST).json({ blockSeconds: `You still blocked` });
}
return res
.status(StatusCodes.BAD_REQUEST)
.json({ blockSeconds: `You was blocked, you can try again after 10 minutes.` });
}
return res.status(StatusCodes.BAD_REQUEST).json({ msg: 'Verification code is invalid' });
}
if (timeDiffInMinutes(dataToCheck.updatedAt) >= +process.env.CODE_EXPIRATION_TIME) {
return res.status(StatusCodes.BAD_REQUEST).json({ msg: 'Verification code expired!' });
}
await this.securityService.resetTries(mobilePhone, id);
return res.status(StatusCodes.OK).json({ msg: 'Success!' });
} catch (error) {
return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({ msg: error.message });
}
};
security.service:
public async updateBlockTime(mobilePhone: string, id: string) {
const { blockedTime } = await getRepository(VerificationEntity).findOne({ mobilePhone: mobilePhone as string, id });
const timestamp = Date.now();
const blockedTimestamp = new Date(timestamp);
await getRepository(VerificationEntity)
.createQueryBuilder()
.update(VerificationEntity)
.set({ blockedTime: blockedTimestamp })
.where({ mobilePhone: mobilePhone as string, id: id as string })
.execute();
return blockedTime;
}

Related

Why my user controller can't get userid property which i have provided in my USERS Schema?

Issue 1: Why my user controller can't get userid property which i have provided in my USERS Schema? i have given a property userid in my Schema which will be a number, but when i am checking my mongobd to see that is userid is coming or not than that userid property is not even showing in my mongobd..
Issue 2: Why my Schema is replicating 3 times whenever i sign up in my app? the Schema is replicating 3 times but every 3 times the mongobd user_id gets change i think its a bug (Note: here the user_id which i am talking about is a user_id which is created by my controller response and in the above issue which i am talking about is a userid that i want to give to my user which will be much smaller and it will be a property)
Mongobd look like this
_id
63613eb2685aa82252cb121b
name
"ecawecawecawce"
phoneNumber
"ewcwaecawecwaecawec"
profileImage
"https://www.pngitem.com/pimgs/m/146-1468479_my-profile-icon-blank-prof…"
selectedCountry
Object
name
"India"
dialCode
"+91"
isoCode
"IN"
flag
"https://cdn.kcak11.com/CountryFlags/countries/in.svg"
__v
0
My Schema
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Users = new Schema({
name: String,
phoneNumber: String,
userid: Number, // Ealier it was a string
profileImage: {
type: String,
default: 'https://www.pngitem.com/pimgs/m/146-1468479_my-profile-icon-blank-profile-picture-circle-hd.png'
},
about: String,
selectedCountry: {
type: Object
}
})
module.exports = mongoose.model("users", Users)
user.controller.js:
const user_module = require('./user.modules');
class user_controller extends user_module {
static create_user = async (req, res) =>{
try {
console.log("controller response",req.body)
let response = await this.save_user_details(req)
let message = 'Success';
res.send({
sucess: true,
message: message,
data: response
})
} catch (error) {
let status_code = error.status.code != undefined ? error.status_code: 500;
let type = error.type != undefined ? err.type: 'Bad Request';
let message = err.custom_msg != undefined ? error.custom_msg: "Something went wrong"
res.status(status_code).send({
sucess: false,
error:type,
message: message
})
}
}
static get_users = async (req, res) =>{
try {
console.log("controller response",req.body)
let response = await this.retrieve_user(req)
let message = 'Success';
res.send({
sucess: true,
message: message,
data: response
})
} catch (error) {
let status_code = error.status.code != undefined ? error.status_code: 500;
let type = error.type != undefined ? err.type: 'Bad Request';
let message = err.custom_msg != undefined ? error.custom_msg: "Something went wrong"
res.status(status_code).send({
sucess: false,
error:type,
message: message
})
}
}
static otp_verify = async (req, res) =>{
try {
console.log("controller response",req.body)
let response = await this.verify_user(req)
if(response.status){
res.send({
success: true,
message: response.message,
data: response.user
})
}else{
res.status(400).send({
success: false,
error: false,
message: response.message
})
}
} catch (error) {
let status_code = error.status_code != undefined ? error.status_code: 500;
let type = error.type != undefined ? err.type: 'Bad Request';
let message = error.custom_msg != undefined ? error.custom_msg: "Something went wrong"
res.status(status_code).send({
sucess: false,
error:type,
message:message
})
res.end();
}
}
}
module.exports = user_controller
user.modules.js:
const models = require('../models');
class user_module {
static save_user_details = async (req) => {
try {
console.log("req body", req.body)
const { profileImage } = req.body
let set_data = req.body
if (!!profileImage) {
set_data.profileImage = profileImage
}
return await models.users.create(set_data)
} catch (error) {
throw error
}
}
static retrieve_user = async (req) => {
try {
let {limit, pagination} = req.query
let query = {}
let projection ={__v: 0}
let options = {
lean: true,
sort: {_id: -1},
skip: !Number(pagination) ? 0: Number(pagination) * !Number(limit) ? 10: Number(limit),
limit: !Number(limit) ? 10: Number(limit)
}
let users = await models.users.find(query, projection, options)
let count = await models.users.count(query)
return {users, count}
} catch (error) {
throw error
}
}
static verify_user = async (req) => {
try {
console.log("req body", req.body)
const { otp, user_id } = req.body
if(otp == '123456'){
let user = await models.users.findById(user_id)
return {user: user, status: true, message: 'success'}
}else{
return {user: null, status: false, message: 'Otp Invalid'}
}
} catch (error) {
throw error
}
}
}
module.exports = user_module
You are not getting the Id because you are trying to get it by user_id, however, It's userid in your model.
Either you have to go with userid OR you have to go with User._id to get your _id which MongoDB creates for every new entry

Express return next() not ending the request

Whenever I send a request, I reach the .then() block and after executing the check(it gets confirmed), the route returns the error as expected. However, the function keeps going and adds the createdAppointment to the database. I've made tried returning just next(), using next(error) only but it keeps giving the same results - it always inserts into the database. Of course, I have the error middleware at the end.
async (err, client) => {
if (err) {
res.status(500).send("Failed Connection!");
return;
}
const forename = req.body.professional.split(" ")[0];
const surname = req.body.professional.split(" ")[1];
const professional = await client
.db("FYP")
.collection("Users")
.findOne({ forename: forename }, { surname: surname });
if (!professional) {
const error = new Error("Professional doesn't match with any in the database")
error.code = 422
return next(error)
}
if(professional.type != "Therapist") {
const error = new Error("The chosen user is not a therapist.")
error.code = 422
return next(error)
}
const user = await client
.db("FYP")
.collection("Users")
.findOne({ _id: res.locals.uid });
const clientUserName = user.forename + " " + user.surname;
const professionalUserName = professional.forename + " " + professional.surname
await client
.db("FYP")
.collection("AppointmentsTherapists")
.find({ client: clientUserName}, { complete: false})
.toArray()
.then(async data => {
if(data) {
console.log(data.length)
for(let i=0; i<data.length; i++) {
console.log(dateInPast(data[i].startTime))
if(dateInPast(data[i].startTime) == false) {
console.log(data[i]._id)
const error = new Error("You already have a booked appointment with a therapist. Please attend the current appointment before booking another.")
error.status = 422
return next(error)
}
}
}
})
if (professionalUserName == clientUserName || user.type == "Therapist" || user.type == "Rehabilitator") {
const error = new Error("A professional cannot book an appointment for themselves.")
error.code = 422
return next(error)
}
const appointment = {
client: clientUserName,
professional: req.body.professional,
information: req.body.information,
startTime: req.body.startTime,
endTime: req.body.endTime,
status: "Pending",
complete: false,
date: new Date()
};
const createdAppointment = await client
.db("FYP")
.collection("AppointmentsTherapists")
.insertOne({ ...appointment });
res.status(200).send(createdAppointment);
return next();
}
);
});
app.use((error, req, res, next) => {
res.status(error.status || 500);
res.json({
message: error.message
})
})
Use async / await or .then() but not both...
let data = await client
.db("FYP")
.collection("AppointmentsTherapists")
.find({ client: clientUserName}, { complete: false})
.toArray()
if(data) {
console.log(data.length)
for(let i=0; i<data.length; i++) {
console.log(dateInPast(data[i].startTime))
if(dateInPast(data[i].startTime) == false) {
console.log(data[i]._id)
const error = new Error("You already have a booked appointment with a therapist. Please attend the current appointment before booking another.")
error.status = 422
return next(error)
}
}
}

cannot handle model.save error and return to FE

I'm trying to save an item to DB using Mongoose and return the saved item or the error to the client.
When making a postman call with a duplicate document i expect to get an error of duplicated, get to the 'catch' statement and retrieve a 500 status code and a message. However, i always get to 'then' with result undefined and status code 200.
I also tried to change the 'throw' to 'return' but with no success. Where i'm wrong?
Route:
router.post("/", (req, res) => {
const schema = Joi.object({
// id: Joi.number().required(),
name: Joi.string().min(3).required(),
description: Joi.string().optional(),
categoryID: Joi.number().required(),
// ingredients: Joi.array().optional(),
price: Joi.number().required(),
vegan: Joi.boolean().required(),
special: Joi.boolean().required(),
img: Joi.string(),
});
let result = schema.validate(req.body);
if (result.error) {
res.status(400).send(result.error);
return;
}
let menu = new Menu();
const {
// id,
name,
description,
categoryID,
ingredients,
price,
vegan,
special,
// img,
} = req.body;
// menu.id = id;
menu.name = name;
menu.categoryID = categoryID;
menu.description = description;
menu.ingredients = ingredients;
menu.price = price;
menu.vegan = vegan;
menu.special = special;
// menu.img = img;
MenuService.saveMenuItem(menu)
.then((result) => {
return res.json(result);
})
.catch((err) => {
return res.status(500).send(err);
});
});
Service:
async function saveMenuItem(menuItem) {
await menuItem.save((err, item) => {
if (err) throw new Error(err.message);
return item;
});
}
module.exports.saveMenuItem = saveMenuItem;
This is the route.
This is the service.
you may should try this:
async function saveMenuItem(menuItem) {
return new Promise((resolve, reject)=>{
menuItem.save((err, item) => {
if (err) reject(err.message);
resolve(item);
})
}

store field value in cloud function variable

I need to get a value from FIRE BASE FIRESTORE and store it in a variable at the cloud function
because I want to compare two variables in an if statement, using node JS the code that I used is shown below:
exports.helloWorld = functions.https.onRequest(
(data, response) => {
const bidder = admin.firestore();
var old = bidder.collection(data['collection'])
.doc(data["doc_id"])
.get();
bidder.collection(data['collection'])
.doc(data["doc_id"])
.get()
.then(
data => {
old = data.data()['price'];
}
);
var newprice = data["new price"];
if (newprice <= old) {
return response.status(500)
.json({ message: 'Not Allowed.' });
} else {
return bidder.collection(data['collection'])
.doc(data["doc_id"])
.update(
{
name_of_bidder: data["name_of_bidder"],
price: data["price"],
phone: data["phone"],
capital: true
},
{ merge: true }
);
}
}
);
Calling get() on a Document Reference returns a Promise, so you have to wait for its end to have access to the data. I think that what you want is this:
exports.helloWorld = functions.https.onRequest(
async (data, response) => {
const bidder = admin.firestore();
var oldDocument = await bidder.collection(data['collection'])
.doc(data["doc_id"])
.get();
var old = oldDocument.data["price"];
var newprice = data["new price"];
if (newprice <= old) {
return response.status(500)
.json({ message: 'Not Allowed.' });
} else {
return bidder.collection(data['collection'])
.doc(data["doc_id"])
.update(
{
name_of_bidder: data["name_of_bidder"],
price: data["price"],
phone: data["phone"],
capital: true
},
{ merge: true }
);
}
}
);

Code executes before i get the response from the database

I am new to Express and writing the code to get the list from my database. I'm trying to update the quantity of the items in my list. Now there can be multiple items and quantity for those items needs to be updated accordingly. The problem I am facing is when I try to get the list and update item accordingly, before my for loop executes to update the item it doesn't update the item's quantity in the database and saves the order. What am I doing wrong?
I have used async functions, promises and flags to update the items quantity in the database but none helps.
This is my code for to get and update the item's quantity
const Express = require("express");
const app = Express.Router();
const Menu = require("../../models/Menu");
const Order = require("../../models/order");
const User = require("../../models/user");
app.post(
"/create",
async function(req, res) {
var myorder = {};
var orderList = [];
var ordDetail = [];
var UpdateMenus = [];
orderList = JSON.parse(JSON.stringify(req.body["OD"]));
if(orderList.length>0){
const user = await User.findOne({ _id: req.user.id })
.then(user => {
if (!user) {
return res.status(400).json({ error: "User Not Found" });
}
})
.then(() => {
var order = Order({
user: req.user.id
});
myorder = order;
(async function loop() {
for (i = 0; i < orderList.length; i++) {
const ordt = new Object({
menu: orderList[i]["menuId"],
order: myorder.id,
prize: orderList[i]["prize"],
quantity: orderList[i]["quantity"]
});
await Menu.findOne({ _id: orderList[i]["menuId"] })
.exec()
.then(menu => {
if (menu) {
if (menu.quantity >= ordt.quantity) {
menu.quantity = menu.quantity - ordt.quantity;
const editmenu = menu;
(async function updateTheMenu() {
await Menu.findOneAndUpdate(
{ _id: menu.id },
{ $set: editmenu },
{
new: true,
useFindAndModify: false
}
).then(updateMenu => {
console.log(updateMenu);
ordDetail.push(ordt);
});
})();
} else {
return res.status(400).json({
error:
menu.MenuText +
"" +
ordt.quantity +
" Qunatity Is Not Available"
});
}
}
});
}
})();
}).then(()=>{
order
.save()
.then(order => {
if (!order) {
return res.json({ error: "Order is not saved" });
}
res.status(200).json(order);
})
.catch(error => {
return res
.status(400)
.json({ error: "Fields are Not Correct" });
});
});
}
}
);
There are few things wrong with your code:
If you use await then you don't need to use then. You can just assign to a variable. Example:
const menu = await Menu.findOne({ _id: orderList[i]["menuId"] })
You don't need to wrap your loop and every await call in async functions. They are already in an async function.
You can write your response handler like this:
app.post('/create', async function(req, res) {
var myorder = {};
var orderList = [];
var ordDetail = [];
var UpdateMenus = [];
orderList = JSON.parse(JSON.stringify(req.body['OD']));
if (orderList.length > 0) {
const user = await User.findOne({ _id: req.user.id });
if (!user) {
return res.status(400).json({ error: 'User Not Found' });
}
var order = Order({
user: req.user.id
});
myorder = order;
for (i = 0; i < orderList.length; i++) {
const ordt = new Object({
menu: orderList[i]['menuId'],
order: myorder.id,
prize: orderList[i]['prize'],
quantity: orderList[i]['quantity']
});
const menu = await Menu.findOne({ _id: orderList[i]['menuId'] });
if (menu) {
if (menu.quantity >= ordt.quantity) {
menu.quantity = menu.quantity - ordt.quantity;
const editmenu = menu;
const updateMenu = await Menu.findOneAndUpdate(
{ _id: menu.id },
{ $set: editmenu },
{
new: true,
useFindAndModify: false
}
);
console.log(updateMenu);
ordDetail.push(ordt);
} else {
return res
.status(400)
.json({
error:
menu.MenuText +
'' +
ordt.quantity +
' Qunatity Is Not Available'
});
}
}
}
try {
const savedOrder = await order.save();
if (!savedOrder) {
return res.json({ error: 'Order is not saved' });
}
res.status(200).json(savedOrder);
} catch (error) {
return res.status(400).json({ error: 'Fields are Not Correct' });
}
}
});

Resources