[TypeError: Cannot read property 'rid' of undefined]
Is the error that I get when I try to execute this controller on my post route.
I've tested it out with Postman.
I've tried to console.log(result) but I get undefined.
My query gets executed and my row is inserted into my table. I've checked it. Password is also hashed.
The problem is that I don't get any out binds that should be returned.
Problematic code (IMO) is
...
.then(function(result) {
console.log(result);
cb(null, {
id: result.outBinds.rid[0],
email: result.outBinds.remail[0],
role: result.outBinds.rrole[0]
});
})
...
oracle-NodeDB Wrapper
var oracledb = require('oracledb');
module.exports.OBJECT = oracledb.OBJECT;
function executeSQL(config ,sql, bindParams , options) {
return new Promise(function(resolve, reject) {
oracledb.getConnection(
config,
function(err, connection) {
if (err) {
return reject(err);
}
connection.execute(
sql,
bindParams,
options,
function(err, result) {
if (err) {
doRelease(connection);
return reject(err);
}
resolve(result);
doRelease(connection);
});
});
});
}
function doRelease(connection) {
connection.release(
function(err) {
if (err) {
console.log(err.message);
}
}
);
}
module.exports.executeSQL = executeSQL;
Controller
var database = require('../database/oracledbWrapper');
var dbconfig = require('../database/dbconfig').dbconfig;
var jwt = require('jsonwebtoken');
var bcrypt = require('bcrypt');
exports.createUser = function(req, res, next) {
var user = {
email: req.body.email
};
var unhashedPassword = req.body.password;
bcrypt.genSalt(10, function(err, salt) {
if (err) {
return next(err);
}
bcrypt.hash(unhashedPassword, salt, function(err, hash) {
if (err) {
return next(err);
}
user.hashedPassword = hash;
insertUser(user, function(err, user) {
var payload;
if (err) {
return next(err);
}
payload = {
sub: user.email,
role: user.role
};
res.status(200).json({
user: user,
token: jwt.sign(payload, config.jwtSecretKey, {expiresInMinutes: 60})
});
});
});
});
}
function insertUser(user, cb) {
var bindParams = {
email: user.email.toLowerCase(),
password: user.hashedPassword,
rid: {
type: database.NUMBER,
dir: database.BIND_OUT
},
remail: {
type: database.STRING,
dir: database.BIND_OUT
},
rrole: {
type: database.STRING,
dir: database.BIND_OUT
}
};
database.executeSQL(
dbconfig,
'insert into express_users (email, password, role ) values ( :email, :password, \'BASE\' ) returning id, email, role into :rid , :remail, :rrole',
bindParams,
{}
)
.then(function(result) {
console.log(result);
cb(null, {
id: result.outBinds.rid[0],
email: result.outBinds.remail[0],
role: result.outBinds.rrole[0]
});
})
.catch(function(err) {
console.log(err);
next(err);
});
}
Route
var RESTfulAPICon = require('../controllers/RESTfulAPI');
var indexCon = require('../controllers/index');
var views = require('express').Router();
views.route('/users').post(RESTfulAPICon.createUser);
exports.views = views;
The problem was in my wrapper , mainly here
module.exports.OBJECT = oracledb.OBJECT;
I export only the OBJECT property , but I try to access BIND_OUT properties later on. And they are non existent.
If I do the full export like this
module.exports.OBJECT = oracledb;
Then I can access BIND_OUT properties.
Related
I'm using passport strategies for different socialMedia logins and getting the following two errors
InternalOAuthError: Failed to fetch user profile
Cannot set headers after they are sent to the client
I have doubt there somewhere I have returned a callback or response so getting 2nd error but for 1st don't know reasons scope seems to be correct!
strategy code
passport.use(new GoogleStrategy({
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_SECRET_KEY,
callbackURL: GOOGLE_CALLBACK_URL
}, async (acessToken, refreshToken, profile, done) => {
await User.findOne({ email: profile._json.email }, async (err, user) => {
if (err) {
console.log("passport.config --> err", err);
done(err, null);
} else if (user) {
if (user.socialType !== "GOOGLE" || user.socialType === null)
done(`LOGIN_CREDENTIALS_WITH_${(user.socialType || "PASSWORD").toUpperCase()}`, false);
else {
done(null, user);
}
} else {
// console.log(profile);
const user = {
email: profile._json.email,
socialId: profile.id,
socialType: "GOOGLE",
firstName: profile.name.givenName,
lastName: profile.name.familyName,
isActive: profile._json.email_verified,
isVerified: profile._json.email_verified,
socialImageUrl: profile._json.picture,
userType: "CUSTOMER"
};
const newUser = new User({ ...user });
const newUserData = await newUser.save();
done(null, newUserData);
}
});
}));
route code:
router.get('/auth/:socialType', customerCtrl.socialTypeLogin);
router.get('/auth/:socialType/callback', customerCtrl.socialTypeLoginCallback);
controller code:
const socialTypeLogin = async (req, res) => {
await customerService.socialTypeLogin(req, res);
};
const socialTypeLoginCallback = async (req,res) => {
await customerService.socialTypeLoginCallback(req,res);
};
service code:
const socialTypeLogin = async (req, res) => {
try {
const socialType = (req.params.socialType || '').toLowerCase();
const GOOGLE_SCOPE = ['email', 'profile'];
const FACEBOOK_SCOPE = ['email'];
let scope = [];
if (socialType === 'google') {
scope = GOOGLE_SCOPE;
} else if (socialType === 'facebook') {
scope = FACEBOOK_SCOPE;
}
let oauthOptions = { scope: scope};
const { returnUrl } = req.query;
if(returnUrl && returnUrl.trim().length !== 0) {
oauthOptions['state'] =JSON.stringify({ returnUrl: returnUrl });
}
passport.authenticate(socialType, oauthOptions)(req, res);
}
catch (error) {
}
}
/**
* #param {string} socialType
*/
const socialTypeLoginCallback = async (req, res) => {
const socialType = (req.params.socialType || '').toLowerCase();
// return new Promise((resolve, reject) => {
try {
passport.authenticate(socialType, async (err, user) => {
let webappRedirectURL = WEBAPP_LOGIN_URL;
try {
const state = req.query.state;
if(state) {
const stateObj = JSON.parse(state);
webappRedirectURL = stateObj.returnUrl;
}
} catch (err1) {
console.log("customer.service --> parsing error",err1);
}
if (err || !user) {
console.log("customer.service --> !user",err);
res.render('oauth-redirect', {
webappRedirectURL: webappRedirectURL,
success: false,
error: err,
timerCounter: 5,
accessToken: undefined
});
}
else {
console.log("customer.service --> Generating Token",user.generateJWT());
res.render('oauth-redirect', {
webappRedirectURL: webappRedirectURL,
success: true,
timerCounter: 5,
accessToken: user.generateJWT(),
error: undefined
});
}
})(req, res);
}
catch (error) {
console.log("customerService.js ==> socialTypeLoginCallback -->",error);
}
};
Thanks for help in advance!
I have doubt there somewhere I have returned a callback or response so getting 2nd error but for 1st don't know reasons scope seems to be correct!
In socialTypeLogin
add line
oauthOptions['session'] = false;
I've got myself two functions, first is responsible for adding a user model to database and second one for comparing passwords. But.. comparing never works..
module.exports.signup = function (req, res) {
if (req.body == null) {
res.status(400);
return res.end('Bad juju');
} else {
let exists;
User.findOne({ username: req.body.username }),
(err, doc) => {
if (doc) {
exists = true;
return;
}
};
if (exists) {
res.setHeader('user-exists', true);
res.redirect('/signup');
} else {
bcrypt.hash(req.body.password, 10, function (hashE, hash) {
if (hashE) {
throw hashE;
}
new User({
username: req.body.username,
email: req.body.email,
password: hash,
}).save();
});
return res.redirect('/login');
}
}
};
module.exports.login = function (req, res) {
if (req.body.tosignup) {
return res.redirect('/signup');
}
if (req.body == null) {
res.status(400);
return res.end('Bad request');
} else {
User.findOne({ username: req.body.username }, (err, doc) => {
if (err) throw console.log(err);
console.log(doc.password);
console.log(req.body.password);
bcrypt.hash(req.body.password, 10, (err, s) => {
console.log(s);
});
bcrypt.compare(req.body.password, doc.password, (err, succ) => {
if (err) {
throw err;
}
console.log(err);
console.log(succ);
if (succ) {
res.setHeader('username', doc.username);
return res.redirect('/welcome');
} else {
res.setHeader('password-wrong', true);
return res.redirect('/login');
}
});
});
}
};
I've looked for different sources and all of them told that this one method is the correct one, but every time I try using it, it just doesn't work
I had a similar problem using bcrypt in nodejs. To solve the problem i switched from npm bcrypt to npm bcryptjs (https://www.npmjs.com/package/bcryptjs) and used the following:
NPM require:
const bcrypt = require('bcryptjs');
To compare the passwords you can use the following code:
async function compareIt(password, hashedPassword) {
const validPassword = await bcrypt.compare(password, hashedPassword);
return validPassword;
}
compareIt(password, passwordBD).then(v => {
if (v == true) {
console.log("Equal");
} else {
console.log("Not equal");
}
});
To hash the password you can use this function:
async function hashIt(password) {
const salt = await bcrypt.genSalt(6);
const hashed = await bcrypt.hash(password, salt);
return hashed;
}
when running the code below im having an Error: Cannot enqueue Query after invoking quit. i need to insert some data into two table .
can you help me to correct the code im really new here in node.js thank you so much.
Create Contact Service.
router.post('/contactinformationdetails', function (req, res, next) {
try {
var reqObj = req.body;
console.log(reqObj);
req.getConnection(function (err, conn) {
if (err) {
console.error('SQL Connection error: ', err);
return next(err);
} else {
var insertSql1 = "INSERT INTO contact_person SET ? ";
var insertValues1 = {
"site_name": reqObj.sitNam,
"first_name": reqObj.firName,
"last_name": reqObj.lastName,
"position": reqObj.posId,
"contact_number": reqObj.conNum,
"organization": reqObj.orga1,
"email_add": reqObj.emaAdd1,
};
var query = conn.query(insertSql1, insertValues1, function (err, result) {
if (err) {
console.error('SQL error: ', err);
return next(err);
}
console.log(result);
var Contact_Id = result.insertId;
res.json({
"Cont_id": Contact_Id
});
var insertSql5 = "INSERT INTO address_contactperson SET ? ";
var insertValues5 = {
"address_name": reqObj.addNam,
"address_one": reqObj.addOne,
"address_two": reqObj.addTwo,
"city": reqObj.city,
"province": reqObj.prov
};
var query1 = conn.query(insertSql5, insertValues5, function (err, result) {
if (err) {
console.error('SQL error: ', err);
return next(err);
}
console.log(result);
});
});
}
});
} catch (ex) {
console.error("Internal error:" + ex);
return next(ex);
}
});
You must try this with mongodb(MongoDB is an open-source document database and leading NoSQL database) the most easy and efficient way.
router.all('/todo/create', function (req, res) {
var taskcreate = req.Collection;
var task = req.body.task;
var date = req.body.date;
var status1 = req.body.status1;
var userid = req.body.userid;
var users = req.Collection;
var record = new taskcreate({
task: task,
date: date,
status1: status1,
userid: userid
});
if (task.length > 0) {
record.save(function (err, result) {
if (err) {
res.json({status: 0, message: err})
} else {
res.json({status: 1, userid: userid, task: task, date: date, message: " success"});
}
})
} else {
res.json({status: 0, msg: "Invalid Fields"});
}
});
The following code is the same code used in the node-oracledb GitHub examples, called select1.js. I just modified it a little bit.
module.exports = function() {
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
this.queryDB = function (query) {
oracledb.getConnection({
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
}, function(err, connection) {
if (err) {
console.error(err.message);
return;
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
console.log(result.metaData);
console.log(result.rows);
doRelease(connection);
return result.rows
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
}
});
}
}
}
This can be used as follow:
require('./dbquery.js')();
console.log(queryDB("SELECT * FROM users"));
I expected to see the same 2D matrix (representing the table) as on line "console.log(result.rows);". But the "console.log(queryDB("SELECT * FROM users"));" returns "undefined".
How can I return a value that I get in the callback function?
I tried to add a variable X at the beginning, like this:
module.exports = function() {
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
this.queryDB = function (query) {
var X;
oracledb.getConnection({
user : dbConfig.user,
password : dbConfig.password,
connectString : dbConfig.connectString
}, function(err, connection) {
if (err) {
console.error(err.message);
return;
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
console.log(result.metaData);
console.log(result.rows);
doRelease(connection);
X = result.rows
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
}
});
}
return X;
}
}
But this is still undefined. How can I achieve this ?
It's running in async nature. You can resolve it with callback or promises. You can't get value like this.
pass the callback and return with callback
module.exports = function(callback) {//pass callback function and return with this
var oracledb = require('oracledb');
var dbConfig = require('./dbconfig.js');
this.queryDB = function(query,callback) {
oracledb.getConnection({
user: dbConfig.user,
password: dbConfig.password,
connectString: dbConfig.connectString
}, function(err, connection) {
if (err) {
console.error(err.message);
return callback(err);
}
connection.execute(query, function(err, result) {
if (err) {
console.error(err.message);
doRelease(connection);
return;
}
console.log(result.metaData);
console.log(result.rows);
doRelease(connection);
return callback(null, result.rows)
});
});
function doRelease(connection) {
connection.release(function(err) {
if (err) {
console.error(err.message);
return callback(err);
}
});
}
};
};
I develop a restful API with nodeJS.
exports.postCreature = function (req, res) {
var creature = new Creature({
name: req.body.name, id_user: req.user._id
});
creature.save(function (err) {
if (err)
res.status(400).send(Error.setError('impossible to save the your creature', err));
else
res.status(201).send();
});
};
//CODE DUPLICATE
exports.createCreature = function(user, callback) {
console.log('Creature created');
var creature = new Creature({
name: user.username, id_user: user._id
});
creature.save(function (err) {
if (err)
callback(err, null);
else
callback(null, creature);
});
}
The two functions execute the same code but not with the same parameters.
I would like to avoid duplication in my code.
How can do in order to avoid duplication of my code ?
I would create another function to handle the redundancies:
function createCreature (creatureName, user, callback) {
console.log('Creature created');
var creature = new Creature({
name: creatureName, id_user: user._id
});
creature.save(function (err, creature) {
if (err)
callback(err, null);
else
callback(null, creature);
});
}
And then in your other functions:
exports.postCreature = function (req, res) {
createCreature(req.body.name, req.user, function (err, creature) {
if (err)
res.status(400).send(Error.setError('impossible to save the your creature', err));
else
res.status(201).send();
};
};
exports.createCreature = function(user, callback) {
console.log('Creature created');
createCreature (user.username, user, callback);
}