Getting Invalid session token(code: 209) while session token exist in _Session table - Parse Server JS SDK - parse-server

I am getting the Invalid session token(code: 209) issue while my session token exist in the _Session table for which i am getting this issue.
Usually This error comes when session token doest not exist in db for which i am just making request but in my case i am getting this issue while session token exist in db.
I am just sharing the cloud code where i am getting this error.
main.js :-
Parse.Cloud.define("ping", function (req, res) {
try {
if (req.user !== undefined) {
var userId = req.params.hasOwnProperty(GameConstants.USER_ID) && req.params.user_id !== "" ? req.params.user_id : req.user.get("username");
LoginHelper.updateUserSessionEndDateTime(userId, function (error, status) {
if (error) {
res.success({result: 0, custom_error_code: error.code, custom_error_message: error.message}); //Getting the error in this block :- {"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}
//custom log
logger.info(JSON.stringify({result: 0, custom_error_code: error.code, custom_error_message: error.message, req: req}));
} else if (status === 0) {
res.success({result: 0, custom_error_code: CustomErrorCode.INVALID_USER_ERROR, custom_error_message: "Inavalid user"});
//custom log
logger.info(JSON.stringify({result: 0, custom_error_code: error.code, custom_error_message: error.message, req: req}));
} else {
res.success({result: 1});
//CommonHelper.recordBuyerSessionData(userId);
}
});
} else {
res.success({result: 0, custom_error_code: CustomErrorCode.INVALID_USER_ERROR, custom_error_message: "Inavalid user"});
//custom log
logger.info(JSON.stringify({result: 0, custom_error_code: CustomErrorCode.INVALID_USER_ERROR, custom_error_message: "Inavalid user", req: req}));
}
} catch (e) {
res.success({result: 0, custom_error_code: e.code, custom_error_message: e.message, stacktrace: e.stack});
//custom log
logger.info(JSON.stringify({result: 0, custom_error_code: e.code, custom_error_message: e.message, stacktrace: e.stack, req: req}));
}
});
LoginHelper.js :-
updateUserSessionEndDateTime: function (userId, callback) {
var query = new Parse.Query(Parse.Object.extend(GameConstants.GAME_USERS));
query.select("session_end_date_time");
query.equalTo(GameConstants.OBJECT_ID, userId);
query.first({
success: function (gameUser) {
if (typeof gameUser !== "undefined") {
//console.log("updateUserSessionEndDateTime data===========> " + JSON.stringify(gameUser));
gameUser.set(GameConstants.SESSION_END_DATE_TIME, new Date());
gameUser.save(null, {
success: function (gameUser) {
//console.log("updateUserSessionEndDateTime.save.success===========> " + JSON.stringify(gameUser));
callback(null, 1);
},
error: function (error) {
//console.log("updateUserSessionEndDateTime.save.error===========> " + error.message);
callback(error);
}
});
} else {
//console.log("updateUserSessionEndDateTime.sessionData-------> undefined ");
callback(null, 0);
}
},
error: function (error) {
//console.log("updateUserSessionEndDateTime.error===========> " + error.message);
callback(error);
}
});
}
Error Logs -
{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}{"result":0,"custom_error_code":209,"custom_error_message":"invalid session token"}
After user login successfully then calling ping cloud function. I don't want to remove ACL to solve this issue. I kindly request you to please help me why i am getting this issue.
Thanks

Cloud code does not automatically pass your session to subsequent server calls. You need to explicitly pass your session token when saving, fetching, etc, if you have put ACL permissions in place that restrict public read/write.
i.e. your save call should be gameUser.save(null, { success:..., error:..., sessionToken:userSessionToken});
Where userSessionToken is found by calling req.user.getSessionToken(); in the original cloud function.

Related

Why is couchdb login good but couchdb session empty, using vuejs and pouchdb

Using Vusjs, pouchdb-browser, CouchDB, pouchdb-authentication
I want to check if a session is open to use for offline stay logged in.
When I login with db.logIn from pouchdb-authentication:
response: {ok: true, name: "01HAYJ", roles: Array(1)}
When I run "getSession" i get userCtx.name as null
session response:
info:
authentication_handlers: Array(2)
0: "cookie"
1: "default"
length: 2
__proto__: Array(0)
__proto__: Object
ok: true
userCtx:
name: null
roles: Array(0)
Here is a snippet of my action:
setUser({commit, dispatch},payload){
console.log('store action payload: ', payload);
var user = payload.user;
var pass = payload.pass
db.logIn(user, pass , function (err, response) {
if (err) {
if (err.name === 'unauthorized' || err.name === 'forbidden') {
alert("Login failed, check user or password!")
} else {
}
}
}).then(function (response) {
// handle response
console.log('response: ', response);
db.getSession(function (err, response) {
if (err) {
// network error
console.log('session error: ', error);
} else if (!response.userCtx.name) {
// nobody's logged in
console.log('nobody is logged in' );
} else {
// response.userCtx.name is the current user
console.log('response.userCtx.name: ', response.userCtx.name );
commit('setUser', response.userCtx.name)
router.push({ name: 'dashboard'})
}
});
commit('setUser', payload.user)
}).catch(function (error) {
// handle error
console.log('error: ', error);
dispatch('logOut');
});
}
There is a mix of callbacks and promises in your code. It is possible that db.login is not completing before the db.session call. I am not sure from the snippet if the "then" is part of another Promise, but here is how I would structure the call:
setUser({commit, dispatch},payload){
console.log('store action payload: ', payload);
var user = payload.user;
var pass = payload.pass
db.logIn(user, pass).then(function (response) {
// handle response
console.log('response: ', response);
return db.getSession();
}).then(response) {
//check user details from the session response here
commit('setUser', payload.user)
}).catch(function (error) {
// handle error
console.log('error: ', error);
dispatch('logOut');
});
}
(this is an example - there may be typos!)

What's the best way to create an LDAP connection to an OpenLDAP server using ldapjs?

I'm getting an error when attempting to create a client connection to an OpenLDAP server. The error message isn't helpful. Am I missing something in the OpenLDAP setup or configuration?
function createLDAPClient () {
return new Promise(function (resolve, reject) {
if(client.connected) return resolve();
client = ldap.createClient({
url: 'ldap://localhost:389',
strictDN: false,
timeout: 10000,
connectTimeout: 10000
//disableQueue: true
});
client.on('connect', function () {
// console.log("LDAP connected");
resolve();
});
client.on('error', function (err) {
// console.log("ldap client error", err);
// idle timeout
if(err.code === 'ECONNRESET') {
return reject();
}
reject();
});
});
}
Getting error
{ InvalidDnSyntaxError: invalid DN
at messageCallback (D:\Sites\Hermes\opt\node_modules\ldapjs\lib\client\client.js:1419:45)
at Parser.onMessage (D:\Sites\Hermes\opt\node_modules\ldapjs\lib\client\client.js:1089:14)
at Parser.emit (events.js:198:13)
at Parser.write (D:\Sites\Hermes\opt\node_modules\ldapjs\lib\messages\parser.js:111:8)
at Socket.onData (D:\Sites\Hermes\opt\node_modules\ldapjs\lib\client\client.js:1076:22)
at Socket.emit (events.js:198:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17) lde_message: 'invalid DN', lde_dn: null
}
The problem was eluding me because I didn't see where the error was being thrown. The answer is to solve the username in the bind function shown here:
function bind (user) {
return new Promise(function (resolve, reject) {
return createLDAPClient()
.then(function () {
//console.log("client should be bound", !client.unbound);
// client.bind(user.username, user.password, function (err) {
// console.log("attempting bind", user);
var ldapuser = user.username;
if( config.ldap.type == 'OpenLDAP'){
ldapuser = 'cn=' + user.username + ',' + config.ldap.dc;
}
client.bind(ldapuser, user.password, function (err) {
//console.log("user bind callback, err:", !!err);
if(err) {
// console.log("error type", typeof err, Object.keys(err), err.stack);
console.error(err);
// bad password
if(err.stack.indexOf("InvalidCredentialsError") !== -1) {
console.log("bad password", user);
reject({
msg: 'Invalid credentials - 101'
});
}
reject({
msg: 'Error connecting to LDAP server',
error: err
});
}
resolve();
});
});
});
}

Using asynchronous methods but Express still returning 503 (NodeJS)

I'm developing a web application in NodeJS with an Express back-end. The application is running smoothly except that when a user signs up, a somewhat long operation is called on the back end that involves saving to a database, resizing an image, etc. It takes a few seconds for this process to complete, and during this time anyone else who makes a request to the server will receive a 503 error and will be unable to do anything, whether that's sending or receiving data. I am using asynchronous functions in order to do this whole process. I am using multer to read the file, fs to read and write the file, and Jimp to resize the image. The code is as shown below.
module.exports = function(router) {
router.route('/')
.post(function(req, res, next) {
upload(req, res, function(err) {
var salt = bcrypt.genSaltSync(saltRounds);
var identifier = makeIdentifier(req.body.first_name.trim())
let emailNotifications = 0;
if (req.body.email_notifications === 'true') {
emailNotifications = 1;
}
var signup = {
identifier: identifier,
first_name: toTitleCase(req.body.first_name.trim()),
last_name: req.body.last_name.trim(),
hobby: req.body.hobby,
type: 'user',
email: req.body.email.trim(),
email_notifications: emailNotifications,
password: bcrypt.hashSync(req.body.password, salt)
};
let ascii = /^[ -~]+$/;
for (var propertyName in signup) {
if (!ascii.test(signup[propertyName])) {
res.json({
reason: "invalid-characters"
});
return;
}
}
if (req.file.size > 5000000) {
res.json({
reason: "file-size"
});
return;
}
let emailExists = false;
db.doesEmailExist(req.body.email, function(err, results) {
if (err) {
res.status(500).send("Server error");
return;
} else {
if (results.length > 0) {
res.json({
reason: "email-exists"
});
return;
} else {
fs.readFile(req.file.path, function(err, data) {
let newPath = __dirname + "/profile-pictures/" + identifier + ".png";
fs.writeFile(newPath, data, function(err) {
if (err) {
console.log(err);
} else {
try {
Jimp.read(newPath, (err, file) => {
if (err) throw err;
file
.resize(300, 300) // resize
.quality(60) // set JPEG quality
.write(newPath); // save
});
} catch (error) {
res.json({
reason: "image-properties"
});
return
}
}
});
});
db.signup(signup, function(err, results) {
if (err) {
res.status(500).send("Server error");
return;
} else {
res.json({
success: true
});
return;
}
})
}
}
})
})
});
}
What is causing the server to respond with a 503 error? Any help would be appreciated, thanks!

Resetting password using express and JWT token

I am trying to reset the user password using the following code and Postman.
But what I realised is that there is no user after I generate the token. the console is saying null;
// Reset User Password
exports.resetPassword = function (req, res) {
User.findOne({
reset_password_token: req.body.token,
reset_password_expires: {
$gt: Date.now()
}
}).exec(function (err, user) {
console.log('this user: ' + user)
if (!err && user) {
if (req.body.newPassword === req.body.verifyPassword) {
user.hash_password = bcrypt.hashSync(req.body.newPassword, 10);
user.reset_password_token = undefined;
user.reset_password_expires = undefined;
user.save(function (err) {
if (err) {
return res.status(422).send({
message: err
});
} else {
console.log(user.hash_password)
}
});
} else {
return res.status(422).send({
message: 'Passwords do not match'
});
}
} else {
return res.status(400).send({
message: 'Password reset token is invalid or has expired.'
});
}
});
};
This is how I use it in Postman
{
"newPassword": "cocacola",
"verifyPassword": "cocacola",
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI1YjI3NjAyNDAwOWI1NDA5ZjMwNzAzZWYiLCJpYXQiOjE1MzA5NjA2NDEwOTN9.1LjroayiTWDNevShnH30n3LxUGCrazmTaJlHgOUNvJ0"
}
and the response in Postman is message from status 400

Node JS Express - Oracle Connection Pooling (ORA-24418: Cannot open further sessions)

I'm having issues with a the Oracle DB module:
https://github.com/oracle/node-oracledb/blob/master/doc/api.md
I have an application which has between 300 and 900 hits per hour (normally from around 100 users). The application has many $.post requests in the background to retrieve information from a database and display to the user.
I've recently switched to this module as it is Oracle's own (I was using https://github.com/joeferner/node-oracle previously).
Here's how I have it set out:
/bin/www
oracledb.createPool(
{
user : 'USER'
password : 'PASS',
connectString : 'DB:1521/SID:POOLED',
connectionClass : 'ARBITRARY_NAME',
poolMin : 1,
poolMax : 50,
poolTimeout : 300
},
function(err, pool)
{
if (err) {
console.log(err);
}
require('../libs/db')(pool); // Export pool to separate file
}
)
/libs/db.js
module.exports = function(pool) {
// Require oracle module for formatting
var oracledb = require('oracledb');
// Export acquire and query function
module.exports.acquire_and_query = function(sql, params, callback){
// ACQUIRE connection from pool
pool.getConnection(function(err, connection){
// NUMBER OF CONNCETIONS OPEN
console.log("ORACLE: CONNX OPEN: " + pool.connectionsOpen);
// NUMBER OF CONNEXTIONS IN USE
console.log("ORACLE: CONNX IN USE: " + pool.connectionsInUse);
if (err) {
console.log(err.message);
return;
}
// Use connection to QUERY db and return JSON object
connection.execute(sql, params, {maxRows: 1000, isAutoCommit: true, outFormat: oracledb.OBJECT}, function(err, result){
// Error Handling
if (err) {
console.log(err.message); // Log the error
return false; // Return false for our error handling
}
// Release the connection back to the pool
connection.release(function(err) {
if (err) {
console.log(err.message);
return;
}
})
// Return callback with rowset first, out bind paramaters second
return callback(result.rows, result.outBinds, result.rowsAffected);
})
})
}
}
This module "acquire_and_query" is called from with in our application, and has SQL and it's params passed in to be executed.
The Oracle DB has a maximum allowed of Pooled connections set to 80 (and we are not exceeding them) - and generally looks pretty happy.
The node application however is constantly throwing out an ORA-24418: Cannot open further sessions, and I am unsure how to resolve this.
Thanks.
Resolved - Issue: My poor coding!
I had unwittingly set a Socket.IO event to update the view for EVERYONE connected multiple times (rather than querying the database once, then sending the view over the socket...) sigh
I was also even more stupidly using a for loop in a transaction based query (which was INSERTing multiple data on each run)... Once I had changed this to a recursive pattern - it went ran swimmingly!
Good article here about for loops and recursive patterns: http://www.richardrodger.com/2011/04/21/node-js-how-to-write-a-for-loop-with-callbacks/#.VaQjJJNViko
Anyway - here's what I use now (and it works rather well)
Using node-oracledb v0.6 (https://github.com/oracle/node-oracledb) and Express 4 (http://expressjs.com/)
bin/www
/**
* Database
*/
// AS PER DOCUMENTATION: https://github.com/oracle/node-oracledb/blob/master/examples/dbconfig.js
var dbconfig = require("../libs/dbconfig.js");
oracledb.connectionClass = dbconfig.connectionClass,
oracledb.createPool({
user: dbconfig.user,
password: dbconfig.password,
connectString: dbconfig.connectString,
poolMax: 44,
poolMin: 2,
poolIncrement: 5,
poolTimeout: 4
}, function(err, pool) {
if (err) {
console.log("ERROR: ", new Date(), ": createPool() callback: " + err.message);
return;
}
require('../libs/oracledb.js')(pool);
});
libs/oracledb.js
module.exports = function(pool) {
////////////////////////////
// INSTANTIATE THE DRIVER //
////////////////////////////
var oracledb = require("oracledb");
//////////////////////
// GET A CONNECTION //
//////////////////////
var doConnect = function(callback) {
console.log("INFO: Module getConnection() called - attempting to retrieve a connection using the node-oracledb driver");
pool.getConnection(function(err, connection) {
// UNABLE TO GET CONNECTION - CALLBACK WITH ERROR
if (err) {
console.log("ERROR: Cannot get a connection: ", err);
return callback(err);
}
// If pool is defined - show connectionsOpen and connectionsInUse
if (typeof pool !== "undefined") {
console.log("INFO: Connections open: " + pool.connectionsOpen);
console.log("INFO: Connections in use: " + pool.connectionsInUse);
}
// Else everything looks good
// Obtain the Oracle Session ID, then return the connection
doExecute(connection, "SELECT SYS_CONTEXT('userenv', 'sid') AS session_id FROM DUAL", {}, function(err, result) {
// Something went wrong, releae the connection and return the error
if (err) {
console.log("ERROR: Unable to determine Oracle SESSION ID for this transaction: ", err);
releaseConnection(connection);
return callback(err);
}
// Log the connection ID (we do this to ensure the conncetions are being pooled correctly)
console.log("INFO: Connection retrieved from the database, SESSION ID: ", result.rows[0]['SESSION_ID']);
// Return the connection for use in model
return callback(err, connection);
});
});
}
/////////////
// EXECUTE //
/////////////
var doExecute = function(connection, sql, params, callback) {
connection.execute(sql, params, { autoCommit: false, outFormat: oracledb.OBJECT, maxRows:1000 }, function(err, result) {
// Something went wrong - handle the data and release the connection
if (err) {
console.log("ERROR: Unable to execute the SQL: ", err);
//releaseConnection(connection);
return callback(err);
}
// Return the result to the request initiator
// console.log("INFO: Result from Database: ", result)
return callback(err, result);
});
}
////////////
// COMMIT //
////////////
var doCommit = function(connection, callback) {
connection.commit(function(err) {
if (err) {
console.log("ERROR: Unable to COMMIT transaction: ", err);
}
return callback(err, connection);
});
}
//////////////
// ROLLBACK //
//////////////
var doRollback = function(connection, callback) {
connection.rollback(function(err) {
if (err) {
console.log("ERROR: Unable to ROLLBACK transaction: ", err);
}
return callback(err, connection);
});
}
//////////////////////////
// RELEASE A CONNECTION //
//////////////////////////
var doRelease = function(connection) {
connection.release(function(err) {
if (err) {
console.log("ERROR: Unable to RELEASE the connection: ", err);
}
return;
});
}
//////////////////////////////
// EXPORT THE FUNCTIONALITY //
//////////////////////////////
module.exports.doConnect = doConnect;
module.exports.doExecute = doExecute;
module.exports.doCommit = doCommit;
module.exports.doRollback = doRollback;
module.exports.doRelease = doRelease;
}
Example Usage
//////////////////////////////
// REQUIRE RELEVANT MODULES //
//////////////////////////////
var db = require("../libs/oracledb.js");
var oracledb = require('oracledb');
var sql = "";
///////////////////////////
// RETRIEVE CURRENT DATE //
///////////////////////////
module.exports.getCurDate = function(callback) {
sql = "SELECT CURRENT_DATE FROM DUAL";
db.doConnect(function(err, connection){
console.log("INFO: Database - Retrieving CURRENT_DATE FROM DUAL");
if (err) {
console.log("ERROR: Unable to get a connection ");
return callback(err);
} else {
db.doExecute(
connection, sql
, {} // PASS BIND PARAMS IN HERE - SEE ORACLEDB DOCS
, function(err, result) {
if (err) {
db.doRelease(connection); // RELEASE CONNECTION
return callback(err); // ERROR
} else {
db.doRelease(connection); // RELEASE CONNECTION
return callback(err, result.rows); // ALL IS GOOD
}
}
);
}
});
}
This error message is raised when the sessMax parameter supplied in OCISessionPoolCreate has been reached.
So, my first move would be verify if database sessions are being closed correctly.
When this error message arises execute the following three actions:
1.- (using sqlplus) show parameter sess
2.- (using sqlplus)
select username,machine,program,count(*) from v$session
group by username,machine ,program
order by 4 ;
3.- verify in alert.log if there are any other ORA- messages during this event.
Did you perform this steps ? (share your results)