The latest version of recaptcha no longer expects a challenge field, the angular-recaptcha directive is up to date with these changes, but none of the node recaptcha libraries work without a challenge field.
How do I validate a recaptcha in node without a challenge field?
function verifyRecaptcha(key, callback) {
https.get("https://www.google.com/recaptcha/api/siteverify?secret=" + recaptcha_vars.privateKey + "&response=" + key, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk.toString();
});
res.on('end', function() {
try {
var parsedData = JSON.parse(data);
console.log(parsedData);
callback(parsedData.success);
} catch (e) {
callback(false);
}
});
});
}
exports.captcha = function(req, res) {
verifyRecaptcha(req.body.response, function(success) {
if (success) {
res.json({ success: true });
// TODO: do registration using params in req.body
} else {
res.json({ success: success, error: "Captcha failed"});
// TODO: take them back to the previous page
// and for the love of everyone, restore their inputs
}
});
};
Related
I have problem with socket.io. In my code router.post(/comment,...) saving user comments in database (using mongoose) and I am trying emit this save. In controller function readMoreCourse is to get and display all comments from database (and question how use socket to this function that using ng-reapat display comment in real-time). Function AddComment is on client side chceck valid form and next post comment to database.
My question: How in real-time save and display user comment using angular (ng-repeat?) and socket.io? Honestly I making this first time, and I have short time, thanks for any help.
Server
io.on('connection', function(socket){
socket.emit('comment', function(){
console.log('Comment emitted')
})
socket.on('disconnect', function(){
})
})
API
router.post('/comment', function(req, res) {
Product.findOne({ _id: req.body._id }, function(err, product){
if(err) {
res.json({ success:false, message: 'Course not found' })
} else {
User.findOne({ username: req.decoded.username }, function(err, user){
if(err){
res.json({ success:false, message: 'Error'})
} else {
product.comments.push({
body: req.body.comment,
author: user.username,
date: new Date(),
});
product.save(function(err){
if(err) throw err
res.json({ success: true, message: 'Comment added })
**io.emit('comment', msg);**
})
}
})
}
})
})
controller
Socket.connect();
User.readMoreCourse($routeParams.id).then(function(data){
if(data.data.success){
app.comments = data.data.product.comments;
} else {
$window.location.assign('/404');
}
});
app.AddComment = function(comment, valid) {
if(valid){
var userComment = {};
userComment.comment = app.comment;
Socket.on('comment', User.postComment(userComment).then(function(data){
if(data.data.success){
$timeout(function(){
$scope.seeMore.comment = '';
},2000)
} else {
app.errorMsg = data.data.message;
}
}));
} else {
app.errorMsg = 'Error';
}
}
$scope.$on('$locationChangeStart', function(event){
Socket.disconnect(true);
})
factory
userFactory.readMoreCourse = function(id) {
return $http.get('/api/seeMore/' + id)
}
userFactory.postComment = function(comment){
return $http.post('/api/comment', comment);
}
.factory('Socket', function(socketFactory){
return socketFactory()
})
In your socket factory, initialize socket.io emit and on events.
app.factory('socket', ['$rootScope', function($rootScope) {
var socket = io.connect();
return {
on: function(eventName, callback){
socket.on(eventName, callback);
},
emit: function(eventName, data) {
socket.emit(eventName, data);
}
};
}]);
and call this from controller
app.controller('yourController', function($scope, socket) {
User.postComment(userComment).then(function(data){
if(data.data.success){
$timeout(function(){
$scope.seeMore.comment = '';
},2000);
// Emit new comment to socket.io server
socket.emit("new comment", userComment);
} else {
app.errorMsg = data.data.message;
}
});
// other clients will listen to new events here
socket.on('newComment', function(data) {
console.log(data);
// push the data.comments to your $scope.comments
});
from socket.io server
io.on('connection', function(socket) {
// listen for new comments from controller and emit it to other clients
socket.on('new comment', function(data) {
io.emit('newComment', {
comment: data
});
});
});
EDIT:
If you just want to push from server side,
io.on('connection', function(socket) {
// after saving your comment to database emit it to all clients
io.emit('newComment', {
comment: data
});
});
and remove this emit code from controller:
socket.emit("new comment", userComment);
But this method can be tricky because the user who posts the comment should immediately see the comment added to the post. If you let socket.io to handle this there will be a few seconds lag for the guy who posted the comment.
I am using angular and talking to an express backend. I can retrieve data from my .get, but my .post is generating a validation error
Client-controller:
$scope.addFriend = function()
{
friendsFactory.addFriend($scope.newFriend, function (data)
{
$location.url('/friends' + data._id);
});
}
Client-factory:
factory.addFriend = function (newFriendData, callback) {
$http.post('/friends', newFriendData)
.then(function(response)
{
console.log(response.data);
//callback(response.data);
})
}
Server-route:
app.post('/friends', function (request, response) {
console.log('routes')
friends.create(request, response);
})
Server-controller:
create: function(request, response)
{
console.log('request');
var friendInstance = new Friend();
friendInstance.first_name = request.params.fname;
friendInstance.last_name = request.params.lname;
friendInstance.b_day = request.params.bday;
friendInstance.save(function(err,data)
{
if (err)
{
response.json(err);
}
else {
rewponse.json(data);
}
})
Error on console:
Object {errors: Object, message: "Friend validation failed", name: "ValidationError"}
this is most likely a mongoose error, the document that you're trying to persist does not follow the Friend schema.
I've having issues with both my routes and getting/saving the data with mongodb. It seems to have validation errors when saving or maybe not posting JSON. Any ideas?
Here's my mongoose schema:
// grab the things we need
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a schema
var sitesEntrySchema = new Schema({
ip: {
type: String,
required: true,
trim: true
},
domain: {
type: String,
required: true,
trim: true
},
wp: {
type: String,
required: true,
trim: true
},
host_name: {
type: String,
required: true
},
hosted: {
type: Number,
required: true
}
});
// make this available to our users in our Node applications
var Site = mongoose.model('Site', sitesEntrySchema);
module.exports = Site;
And my angular http request
var app = angular.module('myApp', []);
app.controller('MainCtrl', function($scope, $http) {
$http.get('/api/mongo')
.then(function(response) {
console.log(response.data);
$scope.myData = response.data;
});
});
app.controller('FormCtrl', function($scope, $http) {
$scope.formData = {};
$scope.addSite = function() {
$http.post('/api/create', $scope.formData)
.success(function(data) {
console.log($scope.formData);
$scope.formData = {}; // clear the form so our user is ready to enter another
swal(
'Good job!',
'Site was added!',
'success'
);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
});
My express routes:
var express = require('express');
var router = express.Router();
var Site = require('../models/site');
//Return From Mongo
router.get('/api/mongo', function(req, res) {
Site.find({}, function(err, sites) {
if (err)
res.send(err)
res.send(sites);
});
//res.json({"yo": "yo this shit works"});
});
//Add A Site
router.post('/api/create', function(req, res, next) {
//create object with form input
var siteData = {
ip: req.body.ip,
domain: req.body.domain,
wp: req.body.wp,
host_name: req.body.host_name,
hosted: req.body.hosted
};
// use schema's 'create' method to insert doc into mongo
Site.create(siteData, function(error) {
if (error) {
//return next(error);
res.send(error);
} else {
return res.json({ message: 'Site added!' });
}
});
});
Without specific outputs that show what is going wrong, here are a few things stick out to me. The first is not always responding with json. You should also try using next() to handle your errors since Express will make sure to send back a correct error response. With these changes, your get route looks like:
//Return From Mongo
router.get('/api/mongo', function(req, res, next) {
Site.find({}, function(err, sites) {
if (err) {
next(err)
} else {
return res.json(sites);
}
});
});
Secondly, It is best practice to return the newly created resource, so your create route should look like
//Add A Site
router.post('/api/create', function(req, res, next) {
//create object with form input
var siteData = {
ip: req.body.ip,
domain: req.body.domain,
wp: req.body.wp,
host_name: req.body.host_name,
hosted: req.body.hosted
};
// use schema's 'create' method to insert doc into mongo
Site.create(siteData, function(error, site) {
if (error) {
next(error);
} else {
return res.json(site);
}
});
});
In addition, depending on your version of Angular, you might be using the deprecated promise syntax for the post request. You should be using .then(), not .success() and .error(). This might also be causing an issue.
Lastly, you should try your best to follow REST guidelines for your routes and responses. It will make it much easier to extend your web app and will keep you more organized. Here is a good Express/Node resource for that https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4.
ADDED: Here is an example of how you can log your errors depending on production/development environments
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
console.log('err:', err.status, err.message);
res.status(err.status || 500);
res.json({message: err.messages});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
I am using ionic framework for my android app and MEANJS on my server. I am using Web Sockets to get realtime data. While the server side web application updates automatically every time a CRUD happens in the android application, the android app does not update automatically when a change is made on the server side.
Android App Service(AngularJS)
.service('Socket', ['Authentication', '$state', '$timeout',
function (Authentication, $state, $timeout) {
// Connect to Socket.io server
this.connect = function () {
// Connect only when authenticated
if (Authentication.user) {
this.socket = io('https://cryptic-savannah-60962.herokuapp.com');
}
};
this.connect();
// Wrap the Socket.io 'on' method
this.on = function (eventName, callback) {
if (this.socket) {
this.socket.on(eventName, function (data) {
$timeout(function () {
callback(data);
});
});
}
};
// Wrap the Socket.io 'emit' method
this.emit = function (eventName, data) {
if (this.socket) {
this.socket.emit(eventName, data);
}
};
// Wrap the Socket.io 'removeListener' method
this.removeListener = function (eventName) {
if (this.socket) {
this.socket.removeListener(eventName);
}
};
}
Client Side Controller
if (!Socket.socket && Authentication.user) {
Socket.connect();
}
Socket.on('orderCreateError', function (response) {
$scope.error = response.message;
});
Socket.on('orderCreateSuccess', function (response) {
if ($scope.orders) {
$scope.orders.unshift(response.data);
}
});
Socket.on('orderUpdateSuccess', function (response) {
if ($scope.orders) {
// not the most elegant way to reload the data, but hey :)
$scope.orders = Orders.query();
}
});
Server Controller(NodeJS)
socket.on('orderUpdate', function (data) {
var user = socket.request.user;
// Find the Order to update
Order.findById(data._id).populate('user', 'displayName').exec(function (err, order) {
if (err) {
// Emit an error response event
io.sockets.emit('orderUpdateError', { data: data, message: errorHandler.getErrorMessage(err) });
} else if (!order) {
// Emit an error response event
io.sockets.emit('orderUpdateError', { data: data, message: 'No order with that identifier has been found' });
} else {
order.name = data.name;
order.phone = data.phone;
order.water = data.water;
order.waiter = data.waiter;
order.napkin = data.napkin;
order.complete = data.complete;
order.rating = data.rating;
order.payment_mode = data.payment_mode;
order.order_source = data.order_source;
order.orderfood = data.orderfood;
order.save(function (err) {
if (err) {
// Emit an error response event
io.sockets.emit('orderUpdateError', { data: data, message: errorHandler.getErrorMessage(err) });
} else {
// Emit a success response event
io.sockets.emit('orderUpdateSuccess', { data: order, updatedBy: user.displayName, updatedAt: new Date(Date.now()).toLocaleString(), message: 'Updated' });
}
});
}
});
});
You have two emit channels on your server side but neither event is handled on the client side.
Per socket.io docs, you need something like:
socket.on('orderUpdateSuccess', function (data) {
// do something inside the app that will update the view
console.log(data);
Orders.update(data); // assuming you have a service called Orders to keep track of live data -- don't forget [$scope.$apply][2]
});
Using your example code
Socket.on('orderUpdateSuccess', function (response) {
if ($scope.orders) {
$scope.$apply(function() {
// not the most elegant way to reload the data, but hey :)
$scope.orders = Orders.query();
});
}
});
In the view html page there is a form with a table and when i submit the form two objects are created cvm and schedules for form and table. i somehow want schedules(which is an array) to be related to cvm form. so i tried this way...
Here is the defined model
$scope.addSchedule=function(schedule)
{
console.log(schedule.startDate);
console.log(schedule.location);
$scope.schedules.push({
startDate: schedule.startDate,
location: schedule.location
});
schedule.startDate='';
schedule.location='';
};
var inData={'cvm': $scope.cvm,'schedules': $scope.schedules};
$scope.addCvm=function()
{
console.log($scope.cvm);
console.log($scope.schedules);
$http.post('/cvmApi',inData).success(function(response) {
console.log(response);
refresh();
});
};
sever side Connection
i guess somthing i missed in this part
/* POST */
router.post('/', function(req, res, next)
{
console.log("Cvm api post '/'");
console.log("retrieving:: " + req.body);
cvmModel.create(req.body, function (err, post) {
console.log("saving:: " + post);
if (err) return next(err);
res.json(post);
});
});
Here is my schema for mongodb
'use strict';
var mongoose = require('mongoose');
var cvmSchema = new mongoose.Schema({
visitOrganization: { type: String },
visitAgenda: { type: String },
accountManager: { type: String },
visitCoordinator: { type: String },
schedules:[{
startDate: String,
location: String
}]
});
module.exports = mongoose.model('visit', cvmSchema);
plz help !! thanks in advance
I think you should try with below change :
//Change addCvm function
$scope.addCvm = function(){
var inData = $scope.cvm;
inData.schedules = $scope.schedules;
console.log(inData);
$http.post('/cvmApi',inData).success(function(response) {
console.log(response);
refresh();
});
};
// Server Side API Code
router.post('/cvmApi', function(req, res, next) {
console.log("Cvm api post '/'");
console.log("retrieving:: " + req.body);
cvmModel.create(req.body, function (err, post) {
console.log("saving:: " + post);
if (err) return next(err);
res.json(post);
});
});
The thing is i dint realize my variable startDate was not in type string in my html page as i was using some date plugins....
soo ya thats it worked brilliantly ...
addCvm function in controller thanks to rana ;-)
$scope.schedules=[];
$scope.addCvm = function(){
var inData = $scope.cvm;
inData.schedules = $scope.schedules;
console.log(inData);
$http.post('/cvmApi',inData).success(function(response) {
console.log(response);
refresh();
});
};
server side Api
router.post('/', function(req, res, next) {
console.log("Cvm api post '/'");
console.log("retrieving:: " + req.body);
cvmModel.create(req.body, function (err, post) {
console.log("saving:: " + post);
if (err) return next(err);
res.json(post);
});
});
may be not required but i changed my schema though....
var cvmSchema = new mongoose.Schema({
visitOrganization: { type: String },
visitAgenda: { type: String },
accountManager: { type: String },
visitCoordinator: { type: String },
schedules: [{
dateStart: { type:String },
locationHere: { type: String }
}]
});