I need to access a mean.js web site page with phantomjs. The problem is I dont know what to include in the header to make it happen.
I can authenticate using http.request and get back the user object. But then I need to somehow take that information and place it in the phantomjs header to allow access to the page.
Here is some code:
'use strict';
var phantom = require('node-phantom-simple');
phantom.create({ path: require('phantomjs').path }, function (err, browser) {
if (err) {
console.log(err);
}
else {
browser.createPage(function (err, page) {
if (err) {
console.log(err);
}
else {
//this is wrong - does not work with mean.js/passport authentication
var authentication_data = { 'Authorization': 'Basic ' + new Buffer('<user>:<password>').toString('base64') };
page.set('customHeaders', authentication_data, function (err) {
if (err) {
console.log(err);
}
else {
var htmlPath = 'http://localhost:3000/path-to-my-web-page';
var complete = false;
page.onConsoleMessage = function (msg) {
console.log('Console: %s', msg);
if (msg === 'the page is loaded') complete = true;
};
return page.open(htmlPath, function (err, status) {
console.log('opened page ', status);
if (err) {
console.log('page.open', err);
}
else {
console.log('opened ' + htmlPath);
//stuff happens here after page is loaded
}
});
}
});
}
});
}
});
I am missing the piece that says it is ok to access the page.
Thanks for your help!
Related
I am making a skill for the Amazon Echo. In my handlers, I have an intent (SelectGardenIntent) that obtains the user_id (needed for following HTTP requests) from the access token successfully, as well as a variable called gardenNumber which is a slot value. To complete the request, I need two other values, the garden_id and the dev_id. I use this gardenNumber and pass it into a function called getGardenId, which will assign the one of the data from the HTTP request to the variable garden_id I have defined in index.js. There are no issues with user_id and gardenNumber. When the function is run, there are no errors from the request, but the callback function with the response is also not executed. The user_id, "about to enter request", and "req done" are correctly logged when tested, but the other log statements in the callback function are not since it is not run. The result is that garden_id is undefined. dev_id is obtained in another method that depends on this garden_id, so dev_id is also undefined. Please help me on this issue. I have pasted the relevant code below.
...
var user_id, garden_id, dev_id;
...
function getGardenId (gardenNumber) {
console.log(user_id);
var path = '/api/rest/client/getgardeninfo?&userid=' + user_id;
var options = {
hostname: server_ip,
port: 80,
path: path,
method: 'GET'
}
console.log("about to enter request");
var req = http.request(options, (res) => {
console.log('entered request');
if (res.statusCode === 200) {
console.log('successful request');
res.setEncoding('utf8');
var body = "";
res.on('data', (chunk) => {
console.log('adding data');
body += chunk.toString();
});
res.on('end', () => {
var obj = JSON.parse(body);
console.log('successfully parsed');
if (obj.error === 200) {
console.log('##gardenid successfully obtained');
garden_id = obj.data[gardenNumber - 1].id;
} else {
console.log("parsing error");
}
});
} else {
console.log("failed request");
}
}); } catch(e) {
console.log("ERROR");
}
req.on('error', (e) => {
console.error(`problem with request: ${e.message}`);
});
req.on('finish', () => {
console.log('ended');
})
req.end();
console.log("req done");
}
...
var handlers = {
...
'SelectGardenIntent': function () {
//var filledSlots = delegateSlotCollection.call(this);
var gardenNumber = this.event.request.intent.slots.Garden.value;
user_id = this.event.session.user.accessToken;
getGardenId(gardenNumber);
getDevId(garden_id);
this.emit(':tell', `OK, garden ${gardenNumber} selected, user id is ${user_id}, garden id is ${garden_id}, device id is ${dev_id}`);
}
...
}
You'd better use npm request to make calls.
request.get({
url: 'http://' + server_ip + '/api/rest/client/getgardeninfo?&userid=' + user_id
}, function (err, res, body) {
console.log(body);
})
I have simple nodejs app with sockets and I've faced an error where I can't find any solution. So I'm emiting from app to client and nothing happens there. Or client can't receive it - I don't know, because I can't check if it was successfully emited to client. This is the error I got when I tried to debug callback of emit:
Error: Callbacks are not supported when broadcasting
This my app code:
http.listen(6060, function () {
console.log("Listening on *: 6060");
});
io.set('authorization', function (handshakeData, accept) {
var domain = handshakeData.headers.referer.replace('http://', '').replace('https://', '').split(/[/?#]/)[0];
if ('***' == domain) {
accept(null, true);
} else {
return accept('You must be logged in to take an action in this site!', false);
}
});
io.use(function (sock, next) {
var handshakeData = sock.request;
var userToken = handshakeData._query.key;
if (typeof userToken !== null && userToken !== 0 && userToken !== '0' && userToken.length > 0) {
connection.query('***',
[xssfilter.filter(validator.escape(userToken))],
function (error, data) {
if (error) {
debug('Cant receive user data from database by token');
next(new Error('Failed to parse user data! Please login!'));
} else {
// load data to this user.
_updateUsers(xssfilter.filter(validator.escape(userToken)), 'add', data[0], sock.id);
_loadPreData();
next(null, true);
}
});
} else {
debug('Cant receive user token');
next(new Error('Failed to parse user data! Please login!'));
}
sock.on("disconnect", function () {
_updateUsers(false, 'remove', false, sock.id);
});
});
// we need to show people online count
io.emit('online-count', {
count: Object.keys(connectedUsers).length
});
And the function used above:
function _updateUsers(userToken, action, userData, sockedID) {
switch (action) {
case 'add':
connectedUsers[sockedID] = {...};
io.emit('online-count', io.emit('online-count', {
count: Object.keys(connectedUsers).length
}););
break;
case 'remove':
delete connectedUsers[sockedID];
io.emit('online-count', io.emit('online-count', {
count: Object.keys(connectedUsers).length
}););
break;
}
}
so after emiting online-count I should accept it on the client side as I'm doing it:
var socket;
socket = io(globalData.socketConn, {query: "key=" + globalData.userData.token});
socket.on('connect', function (data) {
console.log('Client side successfully connected with APP.');
});
socket.on('error', function (err) {
error('danger', 'top', err);
});
socket.on('online-count', function (data) {
console.log('Got online count: ' + data.count);
$('#online_count').html(data.count);
});
but the problem is with this online-count.. Nothing happens and it seems that it's not was even sent from node app. Any suggestions?
The problem was with my logic - I was sending online count only if new user were connecting/disconnecting. Problem were solved by adding function to repeat itself every few seconds and send online count to client side.
Using node js i want to create persistent subscription for Azure service bus service topic. right now it is execute only once. Please guide me I am new to this. Thanks in advance. I am using following code to subscribe topic.
var azure = require('azure');
var azureConnection = "Endpoint=sb:My connection string"
var retryOperations = new azure.ExponentialRetryPolicyFilter();
var serviceBusService = azure.createServiceBusService(azureConnection).withFilter(retryOperations);
serviceBusService.receiveSubscriptionMessage('mytopic01', 'mytopicsub', function (error, receivedMessage) {
if (!error) {
// // // Message received and deleted
console.log(receivedMessage);
}
});
Also I don't want to use setInterval function. I want to solution if message publish to the topic it should automatically trigger subscription.
Actually, if your client application is an independent node.js application, we usually set up a cycle program to receive message from service bus in loop.
E.G.
var azure = require('azure');
var sbService = azure.createServiceBusService(<connection_string>);
function checkForMessages(sbService, queueName, callback) {
sbService.receiveSubscriptionMessage(queueName, { isPeekLock: true }, function (err, lockedMessage) {
if (err) {
if (err === 'No messages to receive') {
console.log('No messages');
} else {
callback(err);
}
} else {
callback(null, lockedMessage);
}
});
}
function processMessage(sbService, err, lockedMsg) {
if (err) {
console.log('Error on Rx: ', err);
} else {
console.log('Rx: ', lockedMsg);
sbService.deleteMessage(lockedMsg, function(err2) {
if (err2) {
console.log('Failed to delete message: ', err2);
} else {
console.log('Deleted message.');
}
})
}
}
setInterval(checkForMessages.bind(null, sbService, queueName, processMessage.bind(null, sbService)), 5000);
You can refer to the code sample in the similar scenario at GitHub provided by Azure Team.
Any further concern, please feel free to let me know.
I'm using Azure Mobile Services(AzMS) in VisualStudio JS-Apache Cordova project where I call a AzMS's custom API to insert user data in storage. This very same code I have previously used in a VS web app javascript and there it is working fine.
However here in the cordova project, I get an "unexpected connection failure" error when calling invokeApi. When I try from VS web app, it works fine, which means the custom API service code is good.
Here is my js client code:
azmsClient.login(oAuthProvider).done(function (results) {
console.log("You are now logged in as: " + results.userId);
var theUserAuthId = results.userId;
azmsClient.invokeApi('Users/insert', {
method: 'POST',
body: { userAuthId: theUserAuthId }
}).done(function (response) {
//.... success code
},
function (error) {
console.log("Error: " + err.request.responseText);
//.... error handling
});
},
function (err) {
console.log("Error: " + err.request.responseText);
//.... error handling
});
In the console log, the first log ("You are now logged in as: "..) gets logged, after that the error - unexpected connection failure.
And my azure custom Api code -
var logger = require('../api/logUtils.js').logger;
exports.register = function(api){
api.post('insert', insertUser);
};
/******************************************************************
* #param request
* #param response
*******************************************************************/
function insertUser(request, response){
var user = request.user;
var iM = "api.User.insertUser-";
logger.info( iM + ' called: - ' , request, response, user);
// Data validation
if ( user.level === 'anonymous' ) {
logger.error( iM + 'Anonymous User' );
response.send(500, { error: "Anonymous user." });
}
user.getIdentities({
success: function (identities) {
var req = require('request');
var userId = user.userId.split(':')[1];
var theProvdr = user.userId.split(':')[0];
var reqParams;
logger.info(iM + ': calling getOAuthUserDetails for Identities: - ' , identities);
try {
reqParams = getOAuthUserDetails(userId, identities);
}
catch(err){
logger.error(iM + ': getOAuthUserDetails - ' , err);
response.send(500, { error: err.message });
return;
}
req.get(reqParams, function (err, resp, body) {
if (err) {
logger.error(iM + ': Error calling provider: ', err);
response.send(500, { error: 'Error calling Authentication provider' });
return;
}
if (resp.statusCode !== 200) {
logger.error(iM + ': Provider call did not return success: ', resp.statusCode);
response.send(500, { error: 'Provider call did not return success: ' + resp.statusCode });
return;
}
try {
logger.info(iM + ': success: got User Details body ', body);
var theAppUser = oAuthUser_To_appUser(theProvdr, JSON.parse(body));
addUser(theAppUser, user, {
success: function(userAlreadyExist, userEnt){
logger.info( iM + ': addUser: success', userEnt);
response.send(200, getAppUserEnt(userEnt));
},
error: function(err){
logger.error( iM + ': Error in addUser: ', err);
response.send(500, { error: err.message });
}
});
} catch (err) {
logger.info(iM + ': Error parsing response: ', err);
response.send(500, { error: err.message });
}
});
},
error: function(err){
logger.info(iM + ': error on calling getIdentities: - ' , err);
response.send(500, { error: err.message });
}
});
In the azure service logs, I see no entry logged from the custom api's user.insert function when running from the cordova project, which means the api is got getting called. Like said before, when calling from VS web project, the log records look all good.
(this is somewhat similar to the issue asked here, but not exactly the same.)
I am unable to figure out why its happening so; any idea?
Are you running on a device, emulator, or Ripple. If its Ripple, you have to change the Cross Domain Proxy to 'disabled'. I had similar issues and this seemed to help.
Im using connect-domain and connect-redis. Below code checks for redis cache in Redis database.
function redis_get(key, req, res) {
var redisClient = redis.createClient();
redisClient.get(redisKey, function (err, data) {
if (err) {
console.log("Error in RedisDB");
}
else if (data == null) {
// Calling external function
}
else {
// Calling external function
}
redisClient.quit(); // Not working
});
}
When cache is not avaiable Im calling external function. I want redis connection to be closed once the cache check has been done.
redisClient.quit() // Not working
Any help on this will be really helpful.
Thanks
Below code is working fine without any problem.So check your status reply in the quit method if you get status as 'OK' means that method is working fine.
var redis=require('redis');
var redisClient = redis.createClient();
redisClient.get('name', function (err, data) {
if (err) {
console.log("Error in RedisDB");
}
else if (data == null) {
console.log('null');
}
else {
console.log(data);
}
redisClient.quit(redis.print);
});