profile validation failed: handle: Path `handle` is required - express

My goal is to build an app that will connect different professionals from different background. I'm also using mongoose as my database.
I created a profile.js that will create and update profiles. But when I test with postman, I get the following error:
"PROFILE VALIDATION FAILED: HANDLE: PATH HANDLE IS REQUIRED."
What can I possibly do to solve this issue?
Your help will be grateful.
const express = require('express'); // require express modules
const router = express.Router(); // to use express router
const auth = require('../../middleware/auth');
const { check, validationResult } = require('express-validator');
const Profile = require('../../models/Profile');
const User = require('../../models/User');
//#route GET api/profile/me
//#desc Get current users profile
//#access Private
router.get('/me', auth, async (req,res) => {
try{
const profile = await Profile.findOne({user: req.user.id}).populate(
'user',
['name', 'avatar']);
if(!profile){
return res.status(400).json({ msg:'No profile exists for this user'});
}
res.json(profile);
} catch(err){
console.error(err.message);
res.status(500).send('Server error');
}
}); //to create a route
//#route POST api/profile
//#desc Create or update users profile
//#access Private
router.post('/',
[
auth,
[
check('status', 'Status is required')
.not()
.isEmpty(),
check('skills', 'Skills is required')
.not()
.isEmpty()
]
] ,
async (req, res) =>{
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({errors: errors.array()})
}
const {
company,
website,
location,
bio,
status,
githubusername,
skills,
youtube,
facebook,
twitter,
instagram,
linkedin
} =req.body;
//to build profile object
const profileFields = {};
profileFields.user = req.user.id
if(company) profileFields.company = company;
if(website) profileFields.website = website;
if(location) profileFields.location = location;
if(bio) profileFields.bio = bio;
if(status) profileFields.status = status;
if(githubusername) profileFields.githubusername = githubusername;
if(skills){
profileFields.skills = skills.split(',').map(skills => skills.trim());
}
//for the social object
profileFields.social = {}
if(youtube) profileFields.social.youtube = youtube;
if(facebook) profileFields.social.facebook = facebook;
if(twitter) profileFields.social.twitter = twitter;
if(instagram) profileFields.social.instagram = instagram;
if(linkedin) profileFields.social.linkedin = linkedin;
try{
let profile = await Profile.findOne({ user: req.user.id });
if(profile){ //if there is a profile, we will update it
profile = await Profile.findOneAndUpdate(
{ user: req.user.id},
{$set: profileFields },
{new: true}
);
return res.json(profile);
}
//this will create profiles
profile = new Profile(profileFields);
await profile.save();
res.json(profile);
} catch(err){
console.error(err.message);
res.status(500).send('Server Error');
}
}
);
module.exports = router;

same code, same issue. In the profile Schema there is a handle field that is set to required. i commented it out and it is working fine now.

the same code you made i made it,you will found handle is required in profile model delete it and your code will working

handle: {
type: String,
required: true,
max: 40
}
Change this code in your models/Profile.js to
handle: {
type: String,
required: false,
max: 40
},

I had the very same Issue . However , it happened because in your "Profile" Schema you probably you made the 'handle' attribute required . So , you must have to give it otherwise just make a change and make the require value to false . Such as (require: false) and hopefully your issue will go .

This is happening because your Profile schema has a handle field(attribute) in which you have a property required: true.
Go to the profile schema file and remove the handle attribute(field) or remove the required: true< from the handle attribute
Example
Profile.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const Profile = new Schema({
...,
handle: {
type: ...,
required: true //remove this line
}
...
});

use
let const profileFields = {};
profileFields.user = req.user.id
that's
let profileFields = {};
profileFields.user = req.user.id
or you can use
const profileFields = {};
profileFields.user = req.user.id;

Related

Express-jwt is not returning any response

I'm trying to create a Login functionality using express-jwt, and using the middleware function in my app.js file. But whenever I'm trying to send a get request using the postman, it sending request for infinite of time and never returns back any error or success message.
I'm using dynamoDB as database.
here's my Login.js file
const AWS = require("aws-sdk");
const express = require("express");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
require("dotenv").config();
AWS.config.update({ region: "us-east-2" });
const docClient = new AWS.DynamoDB.DocumentClient();
const router = express.Router();
router.post("/login", (req, res) => {
user_type = "customer";
const email = req.body.email;
docClient.get(
{
TableName: "users",
Key: {
user_type,
email,
},
},
(err, data) => {
if (err) {
res.send("Invalid username or password");
} else {
if (data && bcrypt.compareSync(req.body.password, data.Item.password)) {
const token = jwt.sign(
{
email: data.Item.email,
},
process.env.SECRET,
{ expiresIn: "1d" }
);
res.status(200).send({ user: data.Item.email, token: token });
} else {
res.status(400).send("Password is wrong");
}
}
}
);
});
module.exports = router;
Here's my jwt.js file:
const expressJwt = require("express-jwt");
require("dotenv").config();
function authJwt() {
const secret = process.env.SECRET;
return expressJwt({
secret,
algorithms: ["HS256"],
});
}
module.exports = authJwt;
And I'm trying to use the expressJwt like this in my app.js file:
app.use(authJwt); //If I'm not using this, then the code works fine without API protection
Can Anyone tell me what's wrong with my code?
Any help from your side is appreciated.
Remove function from your jwt.js ,it should look like this
const expressJwt = require('express-jwt');
const secret = process.env.secret
const authJwt = expressJwt({
secret,
algorithms:['HS256']
})
module.exports = authJwt;

How to change password using passport-local.Strategy and crypto in expressjs?

Below is the code I am trying: index.jsand its not working while changing the password in terms of salt and hash.(saving them in database) I am keep getting the error as setPassword is not defined. Also I think I am committing code errors as well. I want the exact route code for change password using 'passport-local' Strategy.
P.S. I am able to successfully register the user and login as well. I just want to give him the option to change the password.
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
User.findOne({id: req.user.id}, function (err, data) {
console.log("came inside api changePassword else condition inside User.findOne");
if (err) {
console.log(err);
}
else {
data.setPassword(req.body.newPass, function(err,datas){
if(datas) {
data.save(function (err,datass) {
if (err) {
res.render('settingsClient', {errorMessages: err});
} else {
console.log("Hash and Salt saved");
}
});
}
else {
console.log("setPassword error"+ err);
}
});
}
})
This is
Models (user.js) with which I am saving the password at the start of registration of user as hash and salt.
var mongoose = require('mongoose');
var crypto = require('crypto');
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
name: {
type: String,
required: true
},
hash: String,
salt: String
});
userSchema.methods.setPassword = function(password) {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
};
userSchema.methods.validPassword = function(password) {
var hash = crypto.pbkdf2Sync(password, this.salt, 1000, 64, 'sha1').toString('hex');
return this.hash === hash;
};
module.exports = mongoose.model('User', userSchema);

Mock data initialization being subject to Firestore rules

I'm testing a simple rule:
match /users/{userId} {
allow write, get: if isSignedIn() && userOwner(userId);
}
function isSignedIn(){
return request.auth != null
}
function userOwner(userId){
return userId == request.auth.uid
}
Here is my test:
test("read succeed only if requested user is authenticated user", async () => {
const db = await setup(
{
uid: "testid",
email: "test#test.com"
},
{
"users/testid": {},
"users/anotherid": {}
}
);
const userRef = db.collection("users");
expect(await assertSucceeds(userRef.doc("testid").get()));
expect(await assertFails(userRef.doc("anotherid").get()));
})
And the setup method:
export const setup = async (auth?: any, data?: any) => {
const projectId = `rules-spec-${Date.now()}`;
const app = firebase.initializeTestApp({
projectId,
auth
});
const db = app.firestore();
if (data) {
for (const key in data) {
const ref = db.doc(key);
await ref.set(data[key]);
}
}
await firebase.loadFirestoreRules({
projectId,
rules: fs.readFileSync("firestore.rules").toString()
});
return db;
};
It throws the following error :
FirebaseError: 7 PERMISSION_DENIED:
false for 'create' # L5, Null value error. for 'create' # L9
It seems that when it tries to set the mock data given in setup, it can't because of the write rule. but I don't understand, I load the rules after the database being set.
Any idea what's going on here?
You can try setting the rules to be open before you populate the database.
After the data is set you load the rules you are trying to test.
export const setup = async(auth ? : any, data ? : any) => {
const projectId = `rules-spec-${Date.now()}`;
const app = firebase.initializeTestApp({
projectId,
auth
});
const db = app.firestore();
await firebase.loadFirestoreRules({
projectId,
rules:
"service cloud.firestore {match/databases/{database}/documents" +
"{match /{document=**} {" +
"allow read, write: if true;" +
"}}}",
});
if (data) {
for (const key in data) {
const ref = db.doc(key);
await ref.set(data[key]);
}
}
await firebase.loadFirestoreRules({
projectId,
rules: fs.readFileSync("firestore.rules").toString()
});
return db;
};

How to get two tables data in Node.js with object inside other object

I have two tables and I need data in this format. How is this Possible?
My Tables
Required Output
{
"id":"1",
"name":"akhil",
"pics": [
{
"pic1": "123.jpg",
"pic2": "123.jpg"
}
]
}
Generally I use this for getting data from single table
const express = require('express');
const app = express();
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const config = require('./config');
var VerifyToken = require('./VerifyToken');
const mysql = require('mysql');
app.use(express.json());
const connection = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'password',
database : 'sample'
});
app.get('/usersdata', VerifyToken, (req, res) => {
let id = req.userId;
console.log(req.userId);
connection.query("select * from users", function (error, results, fields) {
if (error) throw error;
else {
res.send({"result": results});
}
});
})
My Solution:
app.get('/usersdata', (req, res) => {
connection.query("select u.id, u.name, p.pic1, p.pic2 from users u, pics p where u.usersid=p.id", function (error, results, fields) {
if (error) throw error;
else {
let data = results;
let newResult = {};
results.map(row => {
if(newResult[row.id]) {
newResult[row.id].pics.push(row.pic1, row.pic2)
} else {
newResult[row.id] = { id: row.id, name: row.name, pics: [row.pic1, row.pic2] };
}
})
res.send({ "result": Object.values(newResult) });
}
});
})
I would use an ORM instead of writing query myself. Check this link used for a project saved lot of time and code was cleaner.

Adding mongoose schema model to express results in error 500

I have react app that stores data via axios to a mongoose server. It worked perfect until I wanted to add an extra schema for different data. My schema models are separated so I thought to just add another one called PartyList.js.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// Define collection and schema for Items
var PartyList = new Schema({
name: {
type: String
},
song_id: {
type: String
},
port: {
type: Number
}
},{
collection: 'party'
});
module.exports = mongoose.model('PartyList', PartyList);
This is the code in my app.js.
const config = require('./database/DB');
const ServerPortRouter = require('./routes/ServerPortRoutes');
mongoose.connect(config.DB).then(
() => {console.log('Database is connected') },
err => { console.log('Can not connect to the database' +err)
});
app.use('/serverport', ServerPortRouter);
This is how I import it and try to run it (called ServerPortRoutes.js). After running a part of my application that uses this route I get a 500 (Internal Server Error). My server tells me ReferenceError: PartyList is not defined which is defined 3 lines above.
const ServerPort = require('../models/ServerPort');
const PartyList = require('../models/PartyList');
ServerPortRouter.route('/add-party').post(function (req, res) {
const PartyList = new PartyList(req.body);
PartyList.save()
.then(PartyList => {
res.json('Server added successfully');
})
.catch(err => {
res.status(500).send("unable to save to database");
});
});
The problem looks to be you are redefining a const . In your route change to const partyList = new PartyList(req.body); Then use partyList as your variable