MongoError: Document must be a valid JavaScript object - node.js

I have a problem where MongoDB says that my object is not a valid JavaScript Object, Even though it is! This has been staying for days!
Basically, this is an account system that uses MongoDB's client, and the ObjectId for the ID.
I want to be able to fix the MongoError that says object (sent to updateOne, not filter) is not a valid JavaScript object.
Here is the code:
const { MongoClient, ObjectId } = require("mongodb");
const fs = require("node:fs");
const uri = "mongodb://127.0.0.1:27017";
if (!fs.existsSync("./db")) {fs.mkdirSync("./db")};
const client = new MongoClient(uri,{ useUnifiedTopology: true });
async function conn() {
await client.connect();
}
conn();
const database = client.db("login");
const accs = database.collection("accounts");
const myfil = {
_id: new ObjectId('63b6441832087ccc7e3edea2')
};
const users = accs.findOne(myfil);
const path = require("node:path");
const bcrypt = require('bcrypt');
const env = process.env;
var saltRounds = 10;
const AddSet = class AddSet {
constructor(user,pass) {
console.log(pass);
this.set = {[user]:pass};
this.set = Object.keys(this.set).reduce((acc, key) => {
acc[key.toString()] = this.set[key];
return acc;
}, {});
console.log(this.set);
return this.set;
}
}
const Account = class Account {
constructor(user,password) {
conn();
if (!users[user]) {
conn();
accs.updateOne(myfil,bcrypt.hash(password, saltRounds, function(err, hash)
{
try {
var a = ""+user;
return new AddSet(a.toString(),hash);
} catch(err) {
console.error("bcrypt",err);
}
}));
this.assetDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/assets");
this.metaDir = this.assetDir + '/meta';
this.starterDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/starters");
this.videoDir = path.join(path.join(env.SAVED_FOLDER,"/"+this.user),"/videos");
var fs = require('fs');
if (!fs.existsSync(this.assetDir)) fs.mkdirSync(this.assetDir, { recursive: true });
if (!fs.existsSync(this.starterDir)) fs.mkdirSync(this.assetDir, { recursive: true });
if (!fs.existsSync(this.videoDir)) fs.mkdirSync(this.assetDir, { recursive: true });
}
}
getAssetDir() {
return this.assetDir;
}
getStarterDir() {
return this.starterDir;
}
getVideoDir() {
return this.videoDir;
}
getMetaDir() {
return this.metaDir;
}
checkSession(pswd) {
conn();
bcrypt.compare(pswd, users[this.user], function(err, result) {
if (result) return true;
else return false;
});
}
}
module.exports = { Account, users };
I tried fixing it, making the keys strings, removing the $set, and it did not work.

Related

Error received on token expiration despite of not being outdated in node js app

Good day developers, recently as been working in this node js app, and when implementing jwt library i got an error related to tghe verify() method in this jwt repo.
Kind of :
return secretCallback(null, secretOrPublicKey);
^
TokenExpiredError: jwt expired
The repo is structured in several folders:
controllers
middlewares
helpers
socket controllers
On my middleware folder, sepecifically in a file related to jwt validation i settled this:
file middleware jwt-validation
export {};
const { request, response } = require("express");
const User = require("../models/user-model");
const jwt = require("jsonwebtoken");
const jwtValidator = async (req = request, res = response, next) => {
const token_response = req.header("token-response");
if (!token_response) {
return res.status(401).json({
message: "Not valid token .You don't have authorization",
});
}
try {
const payload = await jwt.verify(token_response, process.env.SECRETKEYJWT)
const userAuth = await User.findById(payload.id);
if (userAuth.userState != true) {
return res.status(401).json({
message: "User inhabilitated",
});
}
if (!userAuth) {
return res.status(404).json({
message: "User not found",
});
}
req.user = userAuth;
next();
} catch (error) {
return res.status(500).json({
message: "Not valid token.Error 500",
});
}
};
module.exports = { jwtValidator };
file middleware jwt-validation-sockets
import { UserSchema } from "../interfaces";
const jwt = require("jsonwebtoken");
const User = require("../models/user-model");
const jwtValidatorRenew = async (
token: string = ""
): Promise<UserSchema | null> => {
if (token == "" || token.length < 10 || token == undefined) {
return null;
}
const payloadToken = await jwt.verify(token, process.env.SECRETKEYJWT)
const userTokenDecoded: UserSchema = User.findById(payloadToken.id);
if (userTokenDecoded?.userState) {
return userTokenDecoded;
} else {
return null;
}
};
module.exports = { jwtValidatorRenew };
file helper jwt-generator
const { request, response } = require("express");
const jwt = require("jsonwebtoken");
const createJWT = async (id = "", nickname = "") =>
return new Promise((resolve, reject) => {
const payloadInJWT = { id, nickname };
jwt.sign(
payloadInJWT,
process.env.SECRETKEYJWT,
{
expiresIn: 3600,
},
//calback
(error:any, token:string) => {
if (error) {
alert(error)
reject("Error creating token ");
} else {
resolve(token);
}
}
);
});
};
module.exports = { createJWT };
file socket-controller
const { jwtValidatorRenew } = require("../middlewares/jwt-validation-socket");
const { userData } = require("../helpers/helper-user-schema-data");
const { Socket } = require("socket.io");
const User = require("../models/user-model");
const {
ChatMessage,
Message,
MessagePrivate,
GroupChat,
} = require("../models/chat-model");
const chatMessage = new ChatMessage()
const socketController = async (socket = new Socket(), io) => {
const user = await jwtValidatorRenew(
socket.handshake.headers["token-response"]
);
try {
...some sockets flags
} catch (error) {
socket.disconnect();
}
};
module.exports = { socketController };

UpdateOne is not working Express and Mongodb

I am trying to update a content in Mongodb with the help of function UpdateOne but I keep getting "0 document(s) matched the filter, updated 0 document(s)". I am not sure what I am doing wrong here.
In the end you can see the attached picture from postman where I am sending the request
doucumnets.js
const database = require('../db/database.js');
const ObjectId = require('mongodb').ObjectId;
const documents = {
updateDoc: async function updateDoc(id, newContent) {
let db;
try {
db = await database.getDb();
const filter = { _id: ObjectId(id) };
const options = { upsert: false };
// // const query = {_id: "633abe851b36b295c11f74b5"};
// // const update = { $set: { contents: "Updated!!!"}};
const updatedDoc = {
$set: {
"contents": newContent
},
};
// console.log(filter);
// const result = await db.collection.updateOne( id, newContent, options );
const result = await db.collection.updateOne( filter, updatedDoc, options );
console.log(
`${result.matchedCount} document(s) matched the filter, updated ${result.modifiedCount} document(s)`,
);
return result;
} catch (error) {
return {
errors: {
message: error.message
}
};
} finally {
await db.client.close();
// console.log(db.close());
}
},
};
module.exports = documents;
route/index.js
const express = require('express');
const router = express.Router();
const documentsModel = require('../models/documents.js');
router.put("/update", async(req, res) => {
try {
const oldId = req.body.id;
const newContent = req.body.newContent;
const result = await documentsModel.updateDoc(oldId, newContent);
return res.status(201).json({ data: result});
} catch (errors) {
console.error(errors.message);
res.send(400).send('Problem with server');
}
});
module.exports = router;

How to handle async/await and promises in node.js confusion

I have checked tons of similiar problems all data, I am so confused. This is returning the same result whether the phone number is in the DB or not. Other versions with async and promises have been crashing the app. Please help
How can I get a value from Firebase realtime DB using the admin SDK and use that value to determine the output. Also it seems abnormally slow at times for some reason
auth.controller.js
const validate = require('../utils/validate');
const { getItem, setItem } = require('../utils/firebase');
const { generatePin } = require('../utils/auth');
const argon2 = require('argon2');
const { error } = require('console');
const { networkInterfaces } = require('os');
const exp = require('constants');
exports.connect = async function (req, res) {
const { phone } = req.body;
if (!phone) {
res.status(400).json({ message: 'Error, phone number is invalid or not registered'})
} else {
if(!validate.phoneNumber(phone)) {
res.status(400).json({ message: 'Error, phone number is invalid or not registered' })
} else {
const result = await generatePin();
item = await setItem('clients', 'phone', phone, 'hash', result.hash)
console.log(item)
if(!item) {
res.status(200).json({ message: 'Success', pin: result.pin})
} else {
res.status(400).json({ message: 'Error, phone number is invalid or not registered' })
}
var currentTime = Date.now();
var expiryTime = currentTime + 60;
setItem('clients', 'phone', phone, 'hashExpiry', expiryTime)
}
}
firebase.js
const { on } = require("events");
var admin = require("firebase-admin");
// Import Admin SDK
const { getDatabase } = require('firebase-admin/database');
const { type } = require("os");
var serviceAccount = require("../fedex-3a42e-firebase-adminsdk-r96f1-7249eaf87b.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://fedex-3a42e-default-rtdb.firebaseio.com/"
});
const db = getDatabase()
function getItem(itemRef, child, val) {
const dbRef = db.ref(itemRef);
dbRef.orderByChild(child).equalTo(val).on("value", (data) => {
return data.val();
});
}
async function setItem(itemRef, child, val, key, pushedVal) {
const value = await getItem(itemRef, child, val);
console.log('val', value)
if(value) {
finallySetItem(value, itemRef, pushedVal);
return true
} else {
return false
}
}
function finallySetItem(data, itemRef, pushedVal) {
console.log(data)
if(data) {
var itemKey = Object.keys(data)[0];
console.log(itemKey)
const dbRef = db.ref(itemRef + '/' + itemKey + '/' + key);
dbRef.set(pushedVal);
}
}
module.exports = { getItem, setItem }
This won't work:
function getItem(itemRef, child, val) {
const dbRef = db.ref(itemRef);
dbRef.orderByChild(child).equalTo(val).on("value", (data) => {
return data.val();
});
}
You're passing your callback to on(), and on() won't do anything with the value you return in there.
More likely you want to use once() and return the value asynchronously from there:
async function getItem(itemRef, child, val) {
const dbRef = db.ref(itemRef);
const data = await dbRef.orderByChild(child).equalTo(val).once("value");
return data.val();
}

Getting error while creating session using Mongoose and node.js

I am trying to manage the transnational data using mongoose and node.js but while creating session its throwing the following error.
Error:
TypeError: session.startTransaction is not a function
at DemoProjectService.transferBalance (/home/anil/Desktop/subhrajyoti/project/demo1/service/account.service.js:32:21)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:189:7)
The below is my service where I am trying to create the session.
async transferBalance(req,res) {
let conn = null;
try{
conn = await connectMasterDb();
if(_.isNull(conn)) {
return false;
}
let from = req.body.from;
let to = req.body.to;
let amount = req.body.amount;
const customerCollection = loadMongoModel('Account');
const session = conn.startSession();
session.startTransaction();
const opts = { session, new: true };
const A = await customerCollection.findOneAndUpdate({ name: from }, { $inc: { balance: -amount } }, opts);
if (A.balance < 0) {
// If A would have negative balance, fail and abort the transaction
// `session.abortTransaction()` will undo the above `findOneAndUpdate()`
throw new Error('Insufficient funds: ' + (A.balance + amount));
}
const B = await customerCollection.findOneAndUpdate({ name: to }, { $inc: { balance: amount } }, opts);
await session.commitTransaction();
session.endSession();
conn.disconnect();
if (_.isEmpty(A) && _.isEmpty(B)) {
return [];
}else{
return { from: A, to: B };
}
}catch(error) {
console.log(error);
return false;
}
}
I am explaining my mongodb connection code file below.
const Mongoose = require('mongoose').Mongoose,
fs = require('fs'),
{ ObjectID } = require('mongodb');
class DemoProjectMongo {
async _connect() {
this.dbInstance = null;
const mongooseInstance = new Mongoose();
const mongodebug = false;
const url = `mongodb://admin:admin#localhost:27017/practice`;
const options = {
useNewUrlParser: true,
useCreateIndex: true,
connectTimeoutMS: 5000000,
poolSize: 10000,
useUnifiedTopology: true,
// autoIndex: false
};
this.dbInstance = await mongooseInstance.connect(url, options);
mongooseInstance.set('bufferCommands', false);
mongooseInstance.set('useFindAndModify', false);
if(mongodebug === true) {
mongooseInstance.set('debug', true);
}
return this.dbInstance;
}
async connectMasterDb() {
return await this. _connect();
}
collection(collectionName) {
try{
const path_name = '/home/anil/Desktop/subhrajyoti/project/demo1/model';
const model = `${path_name}/${collectionName}.model.js`;
if (fs.existsSync(model)) {
let SchemaModel = require(model);
return this.dbInstance.model(collectionName, SchemaModel);
}
}catch(error) {
console.log(error);
}
}
isObjectID(value) {
let response = value;
if (_.isArray(response)) {
response = _.map(response, res => {
if (ObjectID.isValid(res)) {
return new ObjectID(res);
}
return res;
});
} else if (ObjectID.isValid(response)) {
response = new ObjectID(response);
}
return response;
}
}
const edQartMongoUtil = new DemoProjectMongo();
module.exports = {
loadMongoModel: edQartMongoUtil.collection.bind(edQartMongoUtil),
connectMasterDb: edQartMongoUtil.connectMasterDb.bind(edQartMongoUtil),
isObjectID: edQartMongoUtil.isObjectID.bind(edQartMongoUtil)
}
Here I want to manage some transitional record but getting the above error. Can anybody help me to resolve this error.

Seeding mongoDB data in node.js by referencing ObjectId

i'm using mongoose-data-seed to seed data into mongodb, however it has no mechanism to allow passing of ObjectId() as references to other seed files
I found a way to store the output of each of the seeders in a json file and retrieve the ObjectIds from the previous seeds to use in the current seeder. This way i can reference ObjectIds from previous seeders.
seeding-helper.js
const fs = require('fs');
// const path = require('path');
const seedersTmpDataFolder = 'seeders/bin';
class SeedingHelper {
static saveData(filename, data) {
return new Promise((resolve) => {
fs.writeFile(`${seedersTmpDataFolder}/${filename}.json`, JSON.stringify(data, null, '\t'), (err) => {
if (err) throw err;
resolve();
});
});
}
static readData(filename) {
return new Promise((resolve) => {
fs.readFile(`${seedersTmpDataFolder}/${filename}.json`, 'utf8', (err, data) => {
if (err) throw err;
resolve(JSON.parse(data));
});
});
}
}
module.exports = SeedingHelper;
resourceActions.seeder.js
const { Seeder } = require('mongoose-data-seed');
const mongoose = require('mongoose');
const ResourceAction = require('../models/resourceAction');
const SeedingHelper = require('../helpers/seeding-helper');
const { Types: { ObjectId } } = mongoose;
const data = [
{
_id: ObjectId(),
name: 'test1'
},
{
_id: ObjectId(),
name: 'test2'
},
];
class ResourceActionSeeder extends Seeder {
async shouldRun() { // eslint-disable-line class-methods-use-this
return ResourceAction.count().exec().then(count => count === 0);
}
async run() { // eslint-disable-line class-methods-use-this
let result;
await SeedingHelper.saveData('resourceActions', data)
.then(() => {
result = ResourceAction.create(data);
});
return result;
}
}
module.exports = ResourceActionSeeder;
resources.seeder.js
const { Seeder } = require('mongoose-data-seed');
const mongoose = require('mongoose');
const Resource = require('../models/resource');
const SeedingHelper = require('../helpers/seeding-helper');
const { Types: { ObjectId } } = mongoose;
class ResourcesSeeder extends Seeder {
async shouldRun() { // eslint-disable-line class-methods-use-this
return Resource.count().exec().then(count => count === 0);
}
async run() { // eslint-disable-line class-methods-use-this
let result;
await SeedingHelper.readData('resourceActions')
.then((resourceActionsData) => {
const machinesId = ObjectId();
const actionTest1 = ObjectId(resourceActionsData.find(x => x.name === 'test1')._id);
const actionTest2 = ObjectId(resourceActionsData.find(x => x.name === 'test2')._id);
const data = [
{
_id: machinesId,
name: 'machines',
actions: [
actionTest1,
actionTest2,
],
},
];
result = Resource.create(data);
if (result) SeedingHelper.saveData('resources', data);
});
return result;
}
}
module.exports = ResourcesSeeder;

Resources