Not sure if the token is being correctly and safely, mongoose schema - mongodb

Hey guys here is my mongoose schema with a way to create a user token that will be included in a password reset link, I was just wondering if it looked right? Also, not sure how to exactly call a new token, after the User has been created, will a User.save or User.findAndUpdate and then include the token work in the route file? Also, what do I insert inside the token field as a value that will draw from the token encrypted here?
Here is the file:
var mongoose = require('mongoose'),
Schema = mongoose.Schema,
ObjectId = mongoose.Schema.Types.ObjectId,
bcrypt = require('bcrypt-nodejs'),
SALT_WORK_FACTOR = 10;
var crypto = require('crypto');
var UserToken;
var UserSchema = new Schema({
email: { type: String, required: true, lowercase:true, index: { unique: true } },
password: { type: String, required: true },
firstName: {type: String, required: true},
lastName: {type: String, required: true},
phone: {type: Number, required: true},
birthday: {type: Date, required: true},
friendRequest: {type: Object},
notifications: {type: Object},
friend: {type: Object},
date_created: {type: Date},
token: {type: String}
}, {collection: "users"});
UserSchema.statics.new = function(_id, fn) {
var user = new UserToken();
crypto.randomBytes(48, function(ex, buff) {
var token = buff.toString('based64').replace(/\//g, '_').replace(/\+/g, '-');
user.token = _id + '|' + token.toString().slice(1,24);
user._id = _id;
user.save(fn);
});
};
module.exports = mongoose.model('User', UserSchema);

Related

mongoose: validation error on post request

I'm trying to save a new use in mongodb with mongoose, but I am getting ValidationError: "err": "User validation failed:Path 'email' is required., Path 'fname' is required., Path 'username' is required phone: Path phone .despite I make all the data in the body of the post request so:
this is the userModel:
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
_id: {type: Number},
name: {type: String, required: true},
fname: {type: String, required: true},
phone: {type: String, required: true},
email: {type: String, required: true, unique: true},
password: {type: String, required: false},
image: {type: String, required: false},
isAdmin: {type: Boolean, default: false, required: true},
}, {
timeStamps: true
});
const User = mongoose.model('User', userSchema);
export default User;
this is the userRouter.js:
import express from "express";
import data from '../../data.js';
import User from "../userModel.js";
import expressAsyncHandler from "express-async-handler";
import {generateToken} from "../../utils.js";
import bcrypt from "bcryptjs";
const userRouter = express.Router();
let allUsers = data.users;
userRouter.get("/seed", expressAsyncHandler(async(req, res)=>{
//await User.remove({});
const createdUsers = await User.insertMany(allUsers);
res.send({createdUsers});
}));
userRouter.post("/register", expressAsyncHandler(async(req, res)=> {
//await User.remove({});
const user = new User({
name: req.body.name,
fname: req.body.fname,
phone: req.body.phone,
email: req.body.email,
});
const createdUser = await user.save();
res.send({
_id: createdUser._id,
name: createdUser.name,
fname: createdUser.fname,
phone: createdUser.phone,
email: createdUser.email,
token: generateToken(createdUser)
})
}))
export default userRouter;

How to create an array of objects with default values?

how to create an array of objects with default values?
const schema = new mongoose.Schema({
login: {type: String, unique: true, required: true},
password: {type: String, required: true},
chatlist: [
{
channelname: {type: String, default: "frontend"},
channelid: {type: String, default: "619a6bfe5b0931f1e5dbaf2c"}
},
{
channelname: {type: String, default: "backend"},
channelid: {type: String, default: "619a71002954ba23a951bb8f"}
},
{
channelname: {type: String, default: "devops"},
channelid: {type: String, default: "619d69c190a85a40893b6522"}
},
]
})
this code above does not work
when a new user register i want to add a default chats to his profile
next thing is the user must be able to add/remove chats from the database
how should i do this? do the chats need to be an objects or documents?
const schema = new mongoose.Schema({
chatlist: {
type: Array,
defualt: []
}
})
so to have a structure in the array I personally would make the request correct using error handling.
for more information visit this site
didnt find any good solution so i just did this
const schema = new mongoose.Schema({
login: {type: String, unique: true, required: true},
password: {type: String, required: true},
chatlist: [{
channelname: String,
channelid: String
}]
})
const user = await MONGO_user.create({
login: login,
password: hashPassword,
})
user.chatlist.push(
{
channelname: "frontend",
channelid: "619a6bfe5b0931f1e5dbaf2c"
}, {
channelname: "backend",
channelid: "619a71002954ba23a951bb8f"
}, {
channelname: "devops",
channelid: "619d69c190a85a40893b6522"
})
await user.save()

How to make an update on field depending on linked document field

I'm trying to conditionally update a field in a document but I need to know the value of an other field in a linked document. I'm struggling to explain my problem so i will give you my code and try to explain what I'm trying to do.
I got a route to update my 'workstation' collection
router.post("/workstation/update/:id", (req, res, next) => {
const id = req.params.id;
const previousWorkstation = req.body.previous;
const updatedWorkstation = req.body.updated;
const {errors, isValid} = validateWorkstation(updatedWorkstation);
if(!isValid){
return res.status(422).json(errors);
}
Workstation.findByIdAndUpdate(mongoose.Types.ObjectId(id), updatedWorkstation, (err, workstation) => {
if(err) return;
NonConformity.updateMany({workstation: previousWorkstation.name, line: previousWorkstation.line}, {$set:{workstation: updatedWorkstation.name}}, (err) => {
if(err) return;
Rework.updateMany({workstation: previousWorkstation.name}, {$set:{workstation: updatedWorkstation.name}}, (err) => {
if(err) return;
res.send(200);
})
})
})
});
My problem is I need to update rework depending on the line too, and not only the workstation name ! Here are my schemas
// WORKSTATION SCHEMA
const mongoose = require('mongoose');
const WorkstationSchema = mongoose.Schema({
name: {type:String, required: true},
line: {type:String, required: true}
})
const Workstation = mongoose.model('workstations', WorkstationSchema);
module.exports = Workstation;
// REWORK SCHEMA
const mongoose = require('mongoose');
const ReworkSchema = mongoose.Schema({
nonConformity_id: {type:String, required: true},
operator: {type:String, required: true},
fin: {type:String, required: true},
workstation: {type:String, required: false},
code: {type:String, required: true},
declination: {type:String, required: true},
description: {type:String, required: true},
advice: {type:String, required: false},
pps: {type: String, required: false},
quantity: {type:Number, required: true},
reworked: {type:Boolean, default: false, required: true},
verified: {type:Boolean, default: false, required: true},
})
const Rework = mongoose.model('nonConformities.reworks', ReworkSchema);
module.exports = Rework;
// NON CONFORMITY
const mongoose = require('mongoose');
const NonConformitySchema = mongoose.Schema({
number: {type: String, unique: true, required: true, dropDups: true},
line: {type: String, required: true},
product: {type: String, required: true},
workstation: {type: String, required: true},
msn: {type: String, required: true},
date: {type: String, required: true},
type: {type: String, required: true},
})
const NonConformity = mongoose.model('nonConformities', NonConformitySchema);
module.exports = NonConformity;
My question is : Is it possible to update my workstation name in the rework collection depending on the line name of the linked non conformity id in the rework schema ?
Sorry if my english is bad, i can try to reformulate if you don't understand my question.
Thanks in advance !

Mongoose and ExpressJS - modular architecture?

I want to have each file for each model - i.e. user and country.
Currently, I solved this the following way:
person.js
/*jslint node: true */
'use strict';
var mongoose = require('./mongoose'),
Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date,
country: {
type: Schema.Types.ObjectId,
ref: 'Country'
}
});
userSchema.methods.toString = function() {
return `I am ${this.username} and I'm from ${this.country.name}`;
}
module.exports = mongoose.model('Person', userSchema);
country.js
/*jslint node: true */
'use strict';
var mongoose = require('./mongoose'),
Schema = mongoose.Schema;
var countrySchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
created_at: Date,
updated_at: Date,
people: [{
type: Schema.Types.ObjectId,
ref: 'Person'
}]
});
var Country = mongoose.model('Country', countrySchema);
module.exports = Country;
So my question is as follows: how does the mongoose reference two tables? For example, in Person schema, I reference the country by providing ref: 'Country', but I never included the model in the Person.js file. Am I doing something wrong here?
UPDATE:
Taking the below answer into the consideration, I now have 3 files:
database.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/people');
mongoose.set('debug', true);
module.exports = mongoose;
person.js
/*jslint node: true */
'use strict';
var mongoose = require('./database'),
Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
username: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date,
country: {
type: Schema.Types.ObjectId,
ref: 'Country'
}
});
userSchema.methods.toString = function() {
return `I am ${this.username} and I'm from ${this.country.name}`;
}
mongoose.model('Person', userSchema);
country.js
/*jslint node: true */
'use strict';
var mongoose = require('./mongoose'),
Schema = mongoose.Schema;
var countrySchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
created_at: Date,
updated_at: Date,
people: [{
type: Schema.Types.ObjectId,
ref: 'Person'
}]
});
mongoose.model('Country', countrySchema);
Now when I include all these 3 files into a test file, e.g.:
var mongoose = require('./database'),
User = mongoose.model('Person'),
Country = mongoose.model('Country');
I get the following error: MissingSchemaError: Schema hasn't been registered for model "Person". I get the same error for Country if I delete the User variable. It appears as if mongoose is trying to define the model, not retrieve it. What seems to be the problem?
UPDATE 2:
OK, when I include now these documents, I do the following:
require('./person');
require('./country');
var User = require('mongoose').model('Person'),
Country = require('mongoose').model('Country');

Population to sub-scheme in Mongoose

I have two schemas:
Clinic:
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var ProcedureSchema = mongoose.Schema({
name: {
type: String,
trim: true,
required: true
},
alias: {
type: String,
trim: true,
required: true
}
});
var ClinicSchema = mongoose.Schema({
name: {
type: String,
trim: true,
required: true
},
procedures: [ProcedureSchema]
});
module.exports = mongoose.model('Clinic', ClinicSchema);
and Record:
var mongoose = require('mongoose'),
Patient = require('./patient'),
User = require('./user'),
Clinic = require('./clinic'),
Schema = mongoose.Schema;
var RecordSchema = Schema({
doctor: {
type: Schema.Types.ObjectId,
ref: 'User'
},
clinic: {
type: Schema.Types.ObjectId
},
date: {
type: Date
},
patient: {
type: Schema.Types.ObjectId,
ref: 'Patient'
},
procedure: {
type: [Schema.Types.ObjectId],
ref: 'Clinic'
}
});
module.exports = mongoose.model('Record', RecordSchema);
In record schema i store all ids of procedure, which sub-scheme for Clinic
I want to get full object of procedures in record.
I try this query:
Record.find({}).
populate('procedures.procedure').
populate('doctor').
populate('patient').
exec(function(err, records) {
...
});
But get only array of ids, instead array of objects.
Where is problem?
You totally mix all schemes:
populate('procedures.procedure')
But you have not procedures in RecordSchema. Even if it is type mistake, an you mean procedure.procedures - you don't have procedures in ProcedureSchema.
read more about references in MongoDB especially http://docs.mongodb.org/manual/applications/data-models-tree-structures/
Try to make nesting path less than 2. Something like this:
var User,
Procedure,
Clinic,
Patient,
Record;
function defineModels(mongoose, fn) {
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
User = new Schema({
...
});
Procedure = new Schema({
name: { type: String, trim: true, required: true },
alias: { type: String, trim: true, required: true }
});
Clinic = new Schema({
name: { type: String, trim: true, required: true },
procedures: [ProcedureSchema]
});
Patient = new Schema({
...
});
Record = new Schema({
'date': {type: Date, default: Date.now},
'doctor': {type: ObjectId, ref: 'User'},
'clinic': {type: ObjectId, ref: 'Clinic'},
'patient': {type: ObjectId, ref: 'Patient'},
'procedure': {type: ObjectId, ref: 'Procedure'},
});
mongoose.model('User', User);
mongoose.model('Procedure', Procedure);
mongoose.model('Clinic', Clinic);
mongoose.model('Patient', Patient);
mongoose.model('Record', Record);
fn();
}
exports.defineModels = defineModels;
Hope this help.