Integrating Stripe JS with MEAN Stack Application - angularjs

I'm trying to integrate stripe in my MEAN stack application. It's not communicating with Stripe to receive the token. I'm not sure why.
I have stripe source code sourced in my index.html page for my angular application.
It is not communicating with Stripe to receive the token, that console.log never fills, So I know it's not communicating with Stripe for some reason, but the same source code communicates with Stripe in a standalone application. I also believe it is failing when sending server side. I'm trying to send this request from port 3000 to port 8082.
Then I have the below script in another HTML page in my app for stripe:
Stripe.setPublishableKey('pk_test_******************');
var $btn = $('#submit');
$btn.on('click', function() {
$btn.prop('disabled', true);
$btn.button('progress');
var cardNum = $('#card-num').val();
var cardExp = $('#card-exp').val().split('/');
var cardCVC = $('#card-cvc').val();
// First submit the card information to Stripe to get back a token
console.log("starting stripe token");
Stripe.card.createToken({
number: cardNum,
exp_month: cardExp[0],
exp_year: cardExp[1],
cvc: cardCVC
}, function(status, response) {
var $form = $('#form');
var token = response.id;
console.log(response.id);
// Save the token into a hidden input field
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// Now submit the form to our server so it can make the charge against the token
$.post("http://localhost:8082/charge", $form.get(0), function(res) {
console.log("response from charge: " + res);
});
// All done!
$btn.addClass('btn-success').removeClass('btn-primary');
$btn.button('success');
setTimeout(function() {
$('#checkout').modal('hide');
}, 250);
});
return false;
});
I see the console.log response of starting stripe token but it doesn't actually communicate with stripe.
Then here is my server side code:
app.post('/charge', function(req, res) {
// Connect to the db
MongoClient.connect("mongodb://localhost:27017/meanAuth", function(err, db) {
if(!err) {
console.log("We are connected");
}
});
var stripeToken = req.body.stripeToken;
var amount = 1000;
stripe.charges.create({
card: stripeToken,
currency: 'usd',
amount: amount
},
function(err, charge) {
if (err) {
res.send(500, err);
} else {
res.send(204);
}
});
});
My reason for doing this is I'm trying to send user information in my request to the server side code so the server can update a value in my Mongo database.
I need help! Thanks in advance

Related

Email verify in sail.js

I am trying to make a portal for filling up a form for which an applicant needs to create an account before filling out the form. The only issue is how can I stop from spamming the applicant creating account with fake mail. Is it possible to verify email in sail. I have done this in express using node mailer.
var express = require('express');
var nodemailer= require('nodemailer');
var app = express();
var smtpTransport = nodemailer.createTransport("SMTP", {
service: "Gmail",
auth: {
user: "email",
pass: "pass"
}
});
var rand, mailOptions, host, link;
/*---SMTP OVER---*/
/*--Routing Started--*/
app.get('/', function(req , res) {
res.sendfile('index.html');
});
app.get('/send', function(req , res) {
rand=Math.floor((Math.random() * 100) + 54);
host= req.get(host);
link="http://"+req.get('host')+"/verify?id="+rand;
mailOptions={
to : req.query.to,
subject : "Please confirm your Email account",
html : "Hello,<br> Please Click on the link to verify your email.<br>Click here to verify"
}
console.log(mailOptions);
smtpTransport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
res.end("error");
}else{
console.log("Message sent: " + response.message);
res.end("sent");
}
});
});
app.get('/verify',function(req,res){
console.log(req.protocol+":/"+req.get('host'));
if((req.protocol+"://"+req.get('host'))==("http://"+host))
{
console.log("Domain is matched. Information is from Authentic email");
if(req.query.id==rand)
{
console.log("email is verified");
res.end("<h1>Email "+mailOptions.to+" is been Successfully verified");
}
else
{
console.log("email is not verified");
res.end("<h1>Bad Request</h1>");
}
}
else
{
res.end("<h1>Request is from unknown source");
}
});
/*--------------------Routing Over----------------------------*/
app.listen(9999,function(){
console.log("Express Started on Port 3000");
});
Any help will be appreciated Thanks
You should be able to use nodemailer in sails pretty much the same, just change the app.gets into corresponding controller actions.
MailController.js:
module.exports = {
sendVerificationMail: function(req, res) {
// your app.get('/send') code
},
verifyEmail: function(req, res) {
// your app.get('/verify') code
}
}
As a side note, your verifying logic kinda breaks when another user tries to register before the first one has completed his registration:
First user requests for email verification, rand = 34 for example
Second user requests for email verification, rand = 58
First user tries to verify his email with id=34, verification fails since 34 !== 58

private chat using socket.id on socket.io

i am fresher at nodejs and socket.io. i am trying to made a chat application using nodejs, socket.io and angularjs in express framework. i am lacking basic idea how chat is performed privately.up to this stage my code works chatting in a group of connected users. here is my server code
var server = require('http').Server(app);
var io = require('socket.io')(server);
var socket = require('./routes/socket.js');
server.listen(8000);
console.log('server listening on port:8000');
io.on('connection',socket);
and my main socket file consit code like:
module.exports = function(socket){
console.log('connected'+' '+'socketId :'+socket.id);
//console.log(req.session.id);
var users =[];
socket.emit(socket.id);
socket.on('username',function(data){
users.push({id:socket.id,message:data.username});
socket.emit('username', users)
})
socket.on('typing',function(data){
//socket.emit('typing',{message:"helo angular"});
socket.broadcast.emit('typing',{message:data.message});
});
socket.on('typing-stop',function(data){
//socket.emit('typing',{message:"helo angular"});
debugger;
socket.broadcast.emit('typing-stop',{message:data.message});
});
socket.on('new-user',function(data){
socket.emit('new-user',data);
socket.broadcast.emit('new-user',data);
})
socket.on('message',function(data){
users.push({message:data.message});
socket.emit('message',{id:socket.id,message:data.message});
socket.broadcast.emit('message',{id:socket.id,message:data.message});// emit the message to every one connected in server
})
socket.on('disconnect',function(){
console.log('user disconnected');
socket.broadcast.emit('disconnected',{'message':'user left the chat room'});
});
}
i am abe to load all the users who get logged in my app.
all i want is to click to the available and start private messaging, till now chat is public everyone connected in server can see message.
my angularjs controller code goes like:
function orgController(notifyService, chatSocket, $state,$http) {
chatSocket.connect();
var vm = this;
vm.sendMessage = sendMessage;
vm.messages = [];
vm.users = [];
var id = $state.params.id;
$http.get('/users/' + id).then(function(result) {
console.log(result.data);
vm.userData = result.data;
chatSocket.emit('new-user', { 'username': result.data.details.firstName + ' ' + result.data.details.lastName });
});
chatSocket.on('new-user',function(data){
vm.users.push(data);
})
function sendMessage(msg) {
//console.log(msg);
if (msg != null && msg != '') {
chatSocket.emit('message', { message: msg });
vm.msg = '';
} else {
vm.msg = '';
}
}
chatSocket.on('message', function(data) {
//debugger;
console.log(data);
vm.messages.push(data);
});
}
NOTE: i have included angular-socket.io modules and inject its dependency in a service called chatSocket which only return socketFactory.
now i want to click in a user from logged in userlist and start communication. how can i do it from (socket.id). which socket generates or from session id? anyone has better way of doing such. any suggestion and response are highly appreciated.
Basically what you need to do is emit an event to a specific socket like this.
io.to(socket.id).emit('privateMessage', {message: <message goes here>});
then on the client side
socket.on('privateMessage', function(data){
var message = data.message;
//do stuff, display message etc...
});

How to call a function upon http get or post?

I'm sure this is a stupid question but I am very new to the backend so please forgive me.
I am building an angularjs app with express/node also and am trying to integrate PayPal (as a Node.js SDK), what I want is to call the pay method on the SDK from an angular controller and I am doing as follows:
On button click:
// controller
$scope.pay = function(amount) {
PaymentFactory.doPayment(amount);
}
Payment Factory:
// PaymentFactory
return {
doPayment: function(amount) {
$http.get("../../../server/payments/paypal.js")
.then(function(response) {
console.log( response );
})
}
}
Then the server-side file is as below:
require('paypal-adaptive');
var app = require('../../server.js');
var PayPal = require('paypal-adaptive');
var paypalSdk = new PayPal({
userId: 'userid',
password: 'password',
signature: 'signature',
sandbox: true //defaults to false
});
var payload = {
requestEnvelope: {
errorLanguage: 'en_US'
},
actionType: 'PAY_PRIMARY',
currencyCode: 'GBP',
feesPayer: 'EACHRECEIVER',
memo: 'Chained payment example',
cancelUrl: 'returnUrl,
returnUrl: 'cancelUrl',
receiverList: {
receiver: [
{
email: 'email1',
amount: '3.40',
primary:'true'
},
{
email: 'email2',
amount: '1.20',
primary:'false'
}
]
}
};
paypalSdk.pay(payload, function (err, response) {
if (err) {
console.log(err);
} else {
// Response will have the original Paypal API response
// But also a paymentApprovalUrl, so you can redirect the sender to checkout easily
console.log('Redirect to %s', response.paymentApprovalUrl);
return response;
}
});
Of course the get request just returns a string of the server-side file contents, I understand why the above doesn't work but not sure how one would make it work. My aim is to call the PayPal SDK from the angular factory and get back the response so that I can redirect a user to a URL. A direct solution would be helpful but even more so I need pointers to the principles that I am not understanding here as far as how one should call functions upon user actions to get this data from the server side. I have tried searching but I don't really the language to use in my search.
All you need to do is use curl (node-curl npm module). Using curl will help you post data to your paypal url and get back the response. Now you need to handle this response from paypal and accordingly generate your own response to be received by the angular http method.

Using Socket.io, Angular, JWT Authenitication data not available till after user authenticated refresh

I am using Angular and Socket.io, socket-jwt for authentication the sockets, and angular-socket-io on the front end.
When the page loads, the client attempts to connect to the socket.io server. It is denied because their is no token established for the client.
When a socket connection is established I am decoding the token on the server and then I want to emit data to the client including the socket.id where I will update the model and view.
After a user authenticates, it is not until the page is refreshed that the socket.io data is available and then emits to the client.
How do I go about establishing the socket.io connection after the user has logged in and making the data available?
I have tried calling my socket factory, using socket.connect() and io.connect() inside the login controller after a user logs in.
socket factory
app.factory('socket', function ($window, socketFactory) {
var token = $window.localStorage.yourTokenKey;
var myIoSocket = 'http://localhost:8080';
var socket = io.connect(myIoSocket, {'query' : 'token=' + token});
return socket;
});
login function in login controller
$scope.login = function() {
AuthService.login($scope.user)
.then(function(msg) {
socket.connect();
$state.go('home');
}, function() {
console.log('Login Failed');
});
};
server code
var socketIo = require('socket.io');
var io = socketIo.listen(server);
io.use(socketioJwt.authorize({
secret: config.secret,
handshake: true
}));
io.on("connection", function(socket) {
var token = socket.handshake.query.token;
var decoded = jwt.decode(token);
var user = {
name: decoded._doc.name,
userId: decoded._doc._id,
socketId: socket.id
};
socket.emit(‘other event’, user);
});

How to structure my app to use Firebase, Braintree, Ionic/AngularJS, and a minimal nodejs server

Refer to this question: Braintree Dropin UI does not work with Ionic Framework unless force refresh
My current Ionic / Angular / Firebase + a very simple Node server app has security issue when using Braintree to charge user credit card. The problem, according to #RaymondBerg is because client can post any customerId and create a braintree token and charge that customer. Since all my user authorization happened in Firebase / Angular - client side. So when user do a $HTTP.post from my AngularJS/Ionic to my Node server, I don't want to authorize them again (as I don't even know how to do that so I use Firebase).
So what is the strategy here to setup Firebase and my Node server to work with payment system like braintree?
One thing I can think off, is to first create a node in my firebase before http request and then pass in the client $id for request in client side (Ionic app):
$scope.getToken = function () {
var ref = new Firebase('[FirebaseURL]/braintreePaymentToken');
var tokenObj = $firebaseObject(ref.child(posterId));
tokenObj.tokenGenerated = true;
tokenObj.$save().then(function(){
$http({
method: 'POST',
url: 'http://localhost:3000/api/v1/token',
data: {
//user $id from Firebase
userId: snapshot.key(),
}
})
}
In Firebase, I set up a security rule as:
"braintreePayment": {
".read": false,
".write": false,
},
"braintreePaymentToken": {
"$uid": {
".read": "auth != null",
".write": "auth != null && auth.uid == $uid",
}
},
This way, the temp node braintreePaymentToken can ONLY be written by current login user in the app. Other login user (nefarious user) can not write on this node b/c their auth.uid will not equal to posterId, which posterId is the user who need to pay.
On server end, I use once to see if I can find the value:
var ref = new Firebase('[FirebaseURL]');
app.post('/api/v1/token', jsonParser, function (request, response) {
var userId = request.body.userId;
console.log (userId);
//customerId from braintree is stored here so no one except the server can read it
ref.child('braintreePayment').child(userId).once("value", function(snapshot){
var exists = (snapshot.val() !== null);
console.log (exists);
if (exists) {
console.log ("using exsiting customer!");
//If braintreePaymentToken with userId child exsited, it mean this request is come from my Ionic client, not from anywhere else.
ref.child('braintreePaymentToken').child(userId).once("value", function(snap) {
if (snap.val()) {
gateway.clientToken.generate({
customerId: snapshot.val().customerId
}, function (err, res) {
if (err) throw err;
response.json({
"client_token": res.clientToken
});
//After I return the clientToken, I delete the braintreePaymentToken node. It is like using Firebase to send email with Zaiper. More secue I guess?
ref.child('braintreePaymentToken').child(userId).remove();
});
else {
response.json({
"client_token": "Unauthorized Access!"
});
}
} else {
console.log ("using no customer!");
gateway.clientToken.generate({}, function (err, res) {
if (err) throw err;
response.json({
"client_token": res.clientToken
});
});
}
});
});
And when user hit pay button on my client(ionic app), I do the Firebase Once request again to see if the customerId already in my firebase/braintreePayment. If not, we save one with the return transaction customerId created by braintree.
app.post('/api/v1/process', jsonParser, function (request, response) {
var transaction = request.body;
ref.child('braintreePayment').child(transaction.userId).once("value", function(snapshot){
var exists = (snapshot.val() !== null);
console.log (exists);
if (exists) {
console.log ("Return customer!");
gateway.transaction.sale({
amount: transaction.amount,
paymentMethodNonce: transaction.payment_method_nonce,
options: {
submitForSettlement: true
},
}, function (err, result) {
if (err) throw err;
response.json(result);
});
} else {
console.log ("First time customer!");
gateway.transaction.sale({
amount: transaction.amount,
paymentMethodNonce: transaction.payment_method_nonce,
options: {
store_in_vault_on_success: true,
submitForSettlement: true
},
}, function (err, result) {
if (err) throw err;
console.log ("Customer Id: " + result.transaction.customer.id);
var customerId = result.transaction.customer.id;
ref.child('braintreePayment').child(transaction.userId).update({customerId: customerId});
response.json(result);
});
}
});
});
As you see, this is REALLY COMPLICATED. But I do not know a better, secue way to do this...
Is this the best way to structure between Firebase, Node, and Braintree? Is this address the OWASP security concern? Is there way to improve this code to be better or there is a better way to do it?
Thanks!

Resources