Sails.js How to load session and create, check, destroy? - node.js

In config session.js i have enabled redis
before that i have installed these two things...
npm install connect-redis
npm install express
adapter: 'redis',
//
// on localhost is expected.
// Read more about options at: https://github.com/visionmedia/connect-redis
//
host: 'localhost',
port: 6379,
ttl: 3600,
db: 0,
pass: '',
prefix: 'sess:'
In controller 2
//assign the value in session and redirect to controller1
req.session.error = "category Not found";
//error
TypeError: Cannot set property 'error' of undefined
module.exports = {
load_word: function(req, res){
var async = require('async');
var express = require('express');
var RedisStore = require('connect-redis')(express);
async.waterfall([
function(callback){
Category.findOne().where({keyword:req.param('keyword')}).done(function(err,category){
if(category==undefined){
req.session.error = "category Not found";
res.redirect('home');
}else{
category_id = category.id;
}
/*Word.findOne().where({id:category_id}).done(function(err,word){
});*/
});
},
Controller 1
console.log(req.session.error);
module.exports = {
/**
* Action blueprints:
* `/home/index`
* `/home`
*/
index: function (req, res) {
var async = require('async');
var express = require('express');
var RedisStore = require('connect-redis')(express);
var data = new Object();
console.log(req.session.error);
How to solve this ?

To check if category is undefined or not use
if(typeof(category)!='undefined){}

Related

swagger not preserving sessions

I am trying to set up a simple login endpoint in swagger:
//login.js
'use strict';
function login(req, res){
const userId = req.swagger.params.user_id.value;
const user = {
_id: userId
}
if(req.session.userId){
return res.json([req.session.userId, 'hello']);
}
global.app.db.collection('users').insertOne(user, function(err, b){
req.session.userId = userId;
return res.json([req.session]);
});
}
module.exports = {
login: login
};
It seems the if statement is never true, and the userId is never set permanently (it shows up in just the second return statement after the insert statement).
Not sure what is wrong here. My app.js has the typical express-session setup.
//app.js
'use strict';
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const mongoDbUrl = 'mongodb://localhost:27017';
const dbName = 'my_db';
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
var session = require('express-session')
const MongoStore = require('connect-mongo')(session);
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'some secret',
store: new MongoStore({url:mongoDbUrl}),
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
module.exports = app; // for testing
global.app = app;
var config = {
appRoot: __dirname // required config
};
SwaggerExpress.create(config, function(err, swaggerExpress) {
if (err) { throw err; }
// install middleware
swaggerExpress.register(app);
var port = process.env.PORT || 10010;
app.listen(port);
if (swaggerExpress.runner.swagger.paths['/hello']) {
console.log('try this:\ncurl http://127.0.0.1:' + port + '/hello?name=Scott');
}
});
MongoClient.connect(mongoDbUrl, function(err, client) {
assert.equal(null, err);
console.log("Connected successfully to server");
const db = client.db(dbName);
app.db = db;
});
Looks like the problem was this line:
cookie: { secure: true }
secure should have been false because I wasn't using https on my local machine.

MEAN API using node-restful no response

I'm trying to setup API for multiple projects that use same database structure (running on same CMS) but when I'm trying to reach some data I get no response.
index.js
var express = require("express");
var cors = require("cors");
var mongoose = require("mongoose");
var bodyParser = require("body-parser");
var methodOverride = require("method-override");
var _ = require("lodash");
var passport = require("passport");
var dbconfig = require("./app/config/database");
// Create the application
var app = express();
var user = require("./app/routes/User");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Override'));
var connections = [];
// Auto CORS
app.use(cors());
/* Mnual CORS Start
app.use(function(req, res, next){
res.header("Access-Controll-Allow-Origin", "*");
res.header("Access-Controll-Allow-Methods", "GET,PUT,POST,DELETE");
res.header("Access-Controll-Allow-Headers", "Content-Type");
next();
});
/* Manual Cords end */
// Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
require("./app/config/passport")(passport);
app.get("/", (req, res) => {
res.json({ msg: "Nothing here mate" });
});
//------------ THIS IS WORKING ----------------
app.get("/db/:database/navigation", (req, res) => {
var dbname = req.params.database;
var conn = connections[dbname];
var navs = conn.model("navigation", app.models[dbname].navigation);
// Send json data/error
if (navs) navs.find({}, (err, data) => res.json(data));
else res.json({ error: true, msg: "Model not found" });
});
// -------------------------------------------------------
// Setup databases for all projects
_.each(dbconfig.databases, db => {
var appModels = require("./app/models/index");
var processed = 0;
// We will use prefix for all routes /db/:database/
var routePrefix = "/db/" + db.name;
// Use user section
app.use(routePrefix + "/user", user);
// Connection callback - we need to wait for modules to initialize
var connect = () => {
// Initialize connection
connections[db.name] = new mongoose.Mongoose().createConnection(db.url);
// Create some callbacks
connections[db.name].on("connected", () => { console.log("Connected to database " + db.url); });
connections[db.name].on("error", onDatabaseError)
// Once we initialize connection, we need to setup all routes
connections[db.name].once("open", function () {
// Load routes
var routes = require('./app/routes');
// Loop trough routes and use all of them
_.each(routes, function (controller, route) {
var newRoute = routePrefix + route;
app.use(newRoute, controller(app, newRoute, db.name));
});
});
};
// Initialize models
_.each(appModels, (model, index) => {
// Create object if doenst exist
if (app.models == null)
app.models = {};
if (app.models[db.name] == null) {
app.models[db.name] = { [model.name]: model.model };
}
else {
app.models[db.name] = Object.assign(app.models[db.name], { [model.name]: model.model });
}
processed++;
// if this was the last process we are ready to connect
if (processed === appModels.length)
connect();
});
});
app.listen(3000);
app/models/index.js
module.exports = [
{
name: "navigation",
model: require('./Navigation.js')
},
...
];
app/routes.js
module.exports = {
'/navigation': require('./controllers/NavigationController'),
....
};
app/controllers/NavigationController.js
var restful = require("node-restful");
module.exports = function(app, route, dbname){
console.log(route);
var rest = restful.model(
"navigation",
app.models[dbname].navigation
).methods(['get', 'put', 'post', 'delete']);
rest.register(app, route);
// Return middleware
return function(req, res, next){
next();
};
};
Navigation.js is basically just a schema. If I set up route manually like this:
app.get("/db/:database/navigation", (req, res) => {
var dbname = req.params.database;
var conn = connections[dbname];
var navs = conn.model("navigation", app.models[dbname].navigation);
// Send json data/error
if (navs) navs.find({}, (err, data) => res.json(data));
else res.json({ error: true, msg: "Model not found" });
});
it works just fine. I guess I need to assign connection somewhere to restful but I have no idea where. If I use single connection with mongoose.connect() everything works perfectly, but that's not what I need :)
Does anyone have any idea what to do next to get this to work? Will appreciate any help, thanks.
Kind of dug into it and made an extension to change driver reference
Here are all the changes, hope it helps someone in future :)
extensions/restful/index.js
var restful = require("node-restful"),
model = require("./model"),
mongoose = require('mongoose');
exports = module.exports = restful;
exports.model = model;
exports.mongoose = mongoose;
extensions/restful/model.js
exports = module.exports = model;
exports.changeDriver = function(driver){
mongoose = driver;
}
// original model function from node-restful/lib/model.js
function model() {
var result = mongoose.model.apply(mongoose, arguments),
default_properties = defaults();
if (1 === arguments.length) return result;
for (var key in default_properties) {
result[key] = default_properties[key];
}
return result;
}
app/controllers/navigation.js
var restful = require("../extensions/restful");
module.exports = function(app, route, db)
{
restful.model.changeDriver(db.mongoose);
// Setup controller REST
var rest = restful.model(
"navigation",
app.models[db.name].navigation
).methods(['get', 'put', 'post', 'delete']);
// Register this endpoint with the application
rest.register(app, route);
// Return middleware
return function(req, res, next){
next();
};
};
index.js
....
var connect = () => {
// Initialize connection
var $db = databases[_db.name] = {
mongoose: new mongoose.Mongoose(),
name: _db.name
};
$db.mongoose.connect(_db.url);
// Create some callbacks
$db.mongoose.connection.on("connected", () => { console.log("Connected to database " + _db.url); });
$db.mongoose.connection.on("error", (err) => { console.log("Database error: " + err); });
// Once we initialize connection, we need to setup all routes
$db.mongoose.connection.once("open", function () {
// Custom routes for user section
var userRoutes = new UserRoutes($db.mongoose);
app.use(routePrefix + "/user", userRoutes.getRouter());
// Load routes
var routes = require('./app/routes');
// Loop trough routes and use all of them
_.each(routes, function (controller, route) {
var newRoute = routePrefix + route;
app.use(newRoute, controller(app, newRoute, $db));
});
});
};
....

Sharing Session Socket.io Express

I am using the express-socket.io-session and express-mysql-session to share a session between socket.io and express. I do this as follows:
var express = require('express');
var mysql = require('mysql');
var app = express();
var serv = require('http').Server(app);
var io = require('socket.io')(serv, {});
var MySQLStore = require('express-mysql-session');
var options = {
host: "...",
user: "...",
password: "...",
database: "...",
};
var con = mysql.createConnection(options);
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
var sessionStore = new MySQLStore({},con);
var session = require("express-session")({
secret: "...",
resave: true,
saveUninitialized: true,
store : sessionStore
});
var sharedsession = require("express-socket.io-session");
// Use express-session middleware for express
app.use(session);
// Use shared session middleware for socket.io
// setting autoSave:true
io.use(sharedsession(session, {
autoSave:true
}));
Next, I have the following:
app.get('/', function(req, res, next){
console.log(req.session.sessionId);
console.log(req.session.username);
});
Finally:
socket.on('login', function(data) {
socket.handshake.session.sessionId = sessionId;
socket.handshake.session.username = result[0].username;
socket.handshake.session.save();
}
When I check my database, these values are saved correctly. However,
console.log(req.session.sessionId);
console.log(req.session.username);
always prints undefined, even after the login has occurred.

MongoError: not authorized on (DB name) to execute command

I'm using Node.Js, Expressjs, mLab (to host my database) and mongoDB
Im getting an error of not being Authorized on Streetinform(my DB name) to execute command. {listIndexes: "sessions", cursor: {}}
this is the error.
this is how I connect to my Database
var dbHost = process.env.DB_HOST || 'localhost';
var dbPort = process.env.DB_PORT || 3002;
var dbName = process.env.DB_NAME || 'Mongodb';
var dbURL = 'mongodb://'+dbHost+':'+dbPort+'/'+dbName;
if (app.get('env') == 'development'){
// prepend url with authentication credentials //
dbURL = 'mongodb://'+process.env.DB_USER+':'+process.env.DB_PASS+'#'+dbHost+':'+dbPort+'/'+dbName;
}
app.use(session({
secret: 'secret',
proxy: true,
resave: true,
saveUninitialized: true,
store: new MongoStore({ url: dbURL })
})
);
this is my library
var http = require('http');
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var errorHandler = require('errorhandler');
var cookieParser = require('cookie-parser');
var MongoStore = require('connect-mongo')(session);
var dotenv = require('dotenv')
dotenv.load();
var app = express();
Establish Connection to Database
var crypto = require('crypto');
var MongoDB = require('mongodb').Db;
var Server = require('mongodb').Server;
var moment = require('moment');
/*
ESTABLISH DATABASE CONNECTION
*/
var dbName = process.env.DB_NAME || 'mongodb';
var dbHost = process.env.DB_HOST || 'localhost'
var dbPort = process.env.DB_PORT || 3002;
var db = new MongoDB(dbName, new Server(dbHost, dbPort, {autoReconnect: true}), {w: 1});
db.open(function(err, d){
if (err) {
console.log(err);
} else {
if (process.env.NODE_ENV == 'live') {
db.authenticate(process.env.DB_USER, process.env.DB_PASS, function(e, res) {
if (e) {
console.log('mongo :: error: not authenticated', e);
}
else {
console.log('mongo :: authenticated and connected to database :: "'+dbName+'"');
}
});
} else{
console.log('mongo :: connected to database :: "'+dbName+'"');
}
}
});
I to use mLabs to, it appears that you have not created a database uses due to which it cannot execute any commands.
You can enable it using the following steps:
Go to https://mlab.com/home
Click on the database which you are using from the Development and Utility
Click on the Users tab
Click the Add database user button
Enter you desired credentials
So now when you are authenticating pass in the username and password that you have entered in step 5

Node.js Mongoose model not saving without error

Making this simple Node.js Express API I encountered an odd problem:
I am creating a model and inserting data into it and then saving it to my MongoDB. But the record is never saved but I also don't get any error. I have checked if MongoDB is running and both syslog for Node errors and mongod.log for MongoDB errors as well as my own Wilson debug.log file. All contain no errors.
I use postman to test the API and do get a response every time. It's just that the data does not get saved to MongoDB (I used the mongo console with db.collection.find() to check for inserted records).
Any idea why this could be happening?
my code:
api.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var http = require('http');
var https = require('https');
var fs = require('fs');
var winston = require('winston');
// Configure logging using Winston
winston.add(winston.transports.File, { filename: '/home/app/api/debug.log' });
winston.level = 'debug';
// Request body parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// Enable https
var privateKey = fs.readFileSync('path to private key');
var certificate = fs.readFileSync('path to cert file');
var credentials = {
key: privateKey,
cert: certificate
};
// ROUTERS
var router = express.Router();
var speciesRouter = require('./app/routes/speciesRouter');
router.use('/species', speciesRouter);
// Routes prefix
app.use('/api/v1', router);
// SERVER STARTUP
http.createServer(app).listen(3000);
https.createServer(credentials, app).listen(3001);
speciesRouter.js
var express = require('express');
var mongoose = require('mongoose');
var router = express.Router();
var Sighting = require('../models/sighting');
var winston = require('winston');
// Database connection
var dbName = 'dbname';
mongoose.connect('mongodb://localhost:27017/' + dbName);
var db = mongoose.connection;
db.on('error', function(err){
winston.log('debug', err);
});
router.route('/')
.post(function(req, res) {
var sighting = new Sighting();
sighting.user_key = req.body.user_key;
sighting.expertise = req.body.expertise;
sighting.phone_location = req.body.phone_location;
sighting.record_time = req.body.record_time;
sighting.audio_file_location = '/var/data/tjirp1244123.wav';
sighting.probable_species = [{species_name:'Bosaap', percentage:100}];
var error = '';
winston.log('debug', 'test');
// This does not get execute I suspect..
sighting.save(function(err) {
winston.log('debug', 'save');
if (err) {
winston.log('debug', err);
error = err;
}
});
res.json({
probable_species: probable_species,
expertise: req.body.expertise,
error: error
});
});
module.exports = router;
sighting.js (model)
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var SightingSchema = new Schema({
user_key: String,
expertise: Number,
phone_location: { lat: Number, lng: Number },
record_time: Number,
audio_file_location: String,
probable_species: [{ species_name: String, percentage: Number }]
});
module.exports = mongoose.model('Sighting', SightingSchema);
Did you try updating your mongodb.
sudo npm update
You can try using promise.
return sighting.save().then(function(data){
console.log(data); // check if this executes
return res.json({
probable_species: probable_species,
expertise: req.body.expertise,
error: error
});
}).catch(function(err){
console.log(err);
});
One more thing dont use res.json outside the save function because in async code it will run without waiting for save function to complete its execution

Resources