Freeze on connect-redis session destroy? - session

I'm implementing an authentication system in node.js with express backed by a redis database for users and connect-redis for persistant, scalable session stores.
Here is the heart of my app, the server:
// Module Dependencies
var express = require('express');
var redis = require('redis');
var client = redis.createClient();
var RedisStore = require('connect-redis')(express);
var crypto = require('crypto');
var app = module.exports = express.createServer();
// Configuration
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser());
app.use(express.session({ secret: 'obqc487yusyfcbjgahkwfet73asdlkfyuga9r3a4', store: new RedisStore }));
app.use(require('stylus').middleware({ src: __dirname + '/public' }));
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Message Helper
app.dynamicHelpers({
// Index Alerts
indexMessage: function(req){
var msg = req.sessionStore.indexMessage;
if (msg) return '<p class="message">' + msg + '</p>';
},
// Login Alerts
loginMessage: function(req){
var err = req.sessionStore.loginError;
var msg = req.sessionStore.loginSuccess;
delete req.sessionStore.loginError;
delete req.sessionStore.loginSuccess;
if (err) return '<p class="error">' + err + '</p>';
if (msg) return '<p class="success">' + msg + '</p>';
},
// Register Alerts
registerMessage: function(req){
var err = req.sessionStore.registerError;
var msg = req.sessionStore.registerSuccess;
delete req.sessionStore.registerError;
delete req.sessionStore.registerSuccess;
if (err) return '<p class="error">' + err + '</p>';
if (msg) return '<p class="success">' + msg + '</p>';
},
// Session Access
sessionStore: function(req, res){
return req.sessionStore;
}
});
// Salt Generator
function generateSalt(){
var text = "";
var possible= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!##$%^&*"
for(var i = 0; i < 40; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
// Generate Hash
function hash(msg, key){
return crypto.createHmac('sha256', key).update(msg).digest('hex');
}
// Authenticate
function authenticate(username, pass, fn){
client.get('username:' + username + ':uid', function(err, uid){
if (uid !== null){
client.hgetall('uid:' + uid, function(err, user){
if (user.pass == hash(pass, user.salt)){
return fn(null, user);
}
else{
fn(new Error('invalid password'));
}
});
}
else{
return fn(new Error('cannot find user'));
}
});
}
function restrict(req, res, next){
if (req.sessionStore.user) {
next();
} else {
req.sessionStore.loginError = 'Access denied!';
res.redirect('/login');
}
}
function accessLogger(req, res, next) {
console.log('/restricted accessed by %s', req.sessionStore.user.username);
next();
}
// Routes
app.get('/', function(req, res){
res.render('index', {
title: 'TileTabs'
});
});
app.get('/restricted', restrict, accessLogger, function(req, res){
res.render('restricted', {
title: 'Restricted Section'
});
});
app.get('/logout', function(req, res){
req.sessionStore.destroy(function(err){
if (err){
console.log('Error destroying session...');
}
else{
console.log(req.sessionStore.user.username + ' has logged out.');
res.redirect('home');
}
});
});
app.get('/login', function(req, res){
res.render('login', {
title: 'TileTabs Login'
});
});
app.post('/login', function(req, res){
var usernameLength = req.body.username.length;
var passwordLength = req.body.password.length;
if (usernameLength == 0 && passwordLength == 0){
req.sessionStore.loginError = 'Authentication failed, please enter a username and password!';
res.redirect('back');
}
else{
authenticate(req.body.username, req.body.password, function(err, user){
if (user) {
req.session.regenerate(function(){
req.sessionStore.user = user;
req.sessionStore.indexMessage = 'Authenticated as ' + req.sessionStore.user.name + '. Click to logout. ' + ' You may now access the restricted section.';
console.log(req.sessionStore.user.username + ' logged in!');
res.redirect('home');
});
} else {
req.sessionStore.loginError = 'Authentication failed, please check your username and password.';
res.redirect('back');
}
});
}
});
app.get('/register', function(req, res){
res.render('register', {
title: 'TileTabs Register'
});
});
app.post('/register', function(req, res){
var name = req.body.name;
var username = req.body.username;
var password = req.body.password;
var salt = generateSalt();
if (name.length == 0 && username.length == 0 && password.length == 0){
req.sessionStore.registerError = 'Registration failed, please enter a name, username and password!';
res.redirect('back');
}
else{
client.get('username:' + username + ':uid', function(err, uid){
if (uid !== null){
req.sessionStore.registerError = 'Registration failed, ' + username + ' already taken.';
res.redirect('back');
}
else{
client.incr('global:nextUserId', function(err, uid){
client.set('username:' + username + ':uid', uid);
client.hmset('uid:' + uid, {
name: name,
username: username,
salt: salt,
pass: hash(password, salt)
}, function(){
req.sessionStore.loginSuccess = 'Thanks for registering! Try logging in!';
console.log(username + ' has registered!');
res.redirect('/login');
});
});
}
});
}
});
// Only listen on $ node app.js
if (!module.parent) {
app.listen(80);
console.log("Express server listening on port %d", app.address().port);
}
Registration and loggin authentication work great, but for some reason, I'm getting a hang when a connected user attempts to loggout.
As you can see from my /logout route,
app.get('/logout', function(req, res){
req.sessionStore.destroy(function(err){
if (err){
console.log('Error destroying session...');
}
else{
console.log(req.sessionStore.user.username + ' has logged out.');
res.redirect('home');
}
});
});
I have two console.log's to try and determine where the freeze occurs. Interestingly, nothing gets logged.
So, for whatever reason, destroy() isn't being called properly.
I'm not sure whether or not I'm just goofing on syntax, or what, but according to the connect documentation it appears as though I'm setting this up correctly.

You must use req.session instead of req.sessionStore. req.sessionStore is a single RedisStore instance and is not being set dynamically by connect. This means that your code works for one user only. Your users will share the same session data this way.
req.sessionStore has a destroy method too and that's why you are not getting any errors. Your callback is not being called because in this method the callback is the second parameter.
Just replace req.sessionStore for req.session in all your code. E.g.:
req.session.destroy(function(err) { ... });

Related

Service Worker "notificationclick" not firing

The notification is showing fine, but when I click on it, or any of the actions, nothing happens. I see no logging, no error messages, but the notification does close (although it closes even when I comment out the event.notification.close()).
I've tried using the Chrome debugger, and I can set a break point in the code that shows the notification, but all breakpoints within the notificationclick handler fail to pause execution.
I've spent days trying to get this to work and I'm at my wits' end.
const auth = firebase.auth();
const functions = firebase.functions();
const done = functions.httpsCallable("done");
const snooze = functions.httpsCallable("snooze");
self.addEventListener("notificationclick", event => {
console.log("notificationclick", event);
const uid = auth.currentUser.uid;
const { id, url } = event.notification.data;
event.notification.close();
event.waitUntil(() => {
switch (event.action) {
case "done":
console.log("Done");
return done({ uid, id });
case "snooze1":
console.log("Snooze 1 Hour");
return snooze({ uid, id, hours: 1 });
case "snooze24":
console.log("Snooze 1 Day");
return snooze({ uid, id, hours: 24 });
default:
console.log("Open App");
return clients
.matchAll({
includeUncontrolled: true,
type: "window"
})
.then(clientList => {
for (let i = 0; i < clientList.length; i++) {
let client = clientList[i];
if (url[0] === "#") {
if (client.url.endsWith(url) && "focus" in client) {
return client.focus();
}
} else {
if (
client.url.replace(/#.*$/, "") === url &&
"focus" in client
) {
return client.focus();
}
}
}
if (clients.openWindow) {
return clients.openWindow(location.origin + url);
}
});
}
});
});
firebase
.messaging()
.setBackgroundMessageHandler(({ data: { title, options } }) => {
options = JSON.parse(options);
options.actions = [
{ action: "done", title: "Done" },
{ action: "snooze1", title: "Snooze 1 Hour" },
{ action: "snooze24", title: "Snooze 1 Day" }
];
return self.registration.showNotification(title, options);
});
Hi Could you try below code and see if this is getting called-
self.addEventListener('notificationclick', function (event) {
event.notification.close();
var redirectUrl = null;
var tag = event.notification.tag;
if (event.action) {
redirectUrl = event.action
}
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: !0
});
var chatClient;
for (const client of allClients) {
if (redirectUrl != '/' && client.url.indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient
}
}().then(result => {
if (tag) {
//PostAction(tag, "click")
}
}))
}
});
Edited-
Attaching both js files. it is working at my end.
firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload.data);
var notificationTitle = payload.data.Title;
var notificationOptions = {
body: payload.data.Body,
icon: payload.data.Icon,
image: payload.data.Image,
action: payload.data.ClickAction
};
console.log("strated sending msg" + notificationOptions);
return self.registration.showNotification(notificationTitle,notificationOptions);
});
self.addEventListener('notificationclick', function (event) {
console.log('On notification click: ', event.notification);
event.notification.close();
var redirectUrl = null;
if (event.notification.data) {
if (event.notification.data.FCM_MSG) {
redirectUrl = event.notification.data.FCM_MSG.data ? event.notification.data.FCM_MSG.data.click_action : null
} else {
redirectUrl = event.notification.data ? event.notification.data.click_action : null
}
}
console.log("redirect url is : " + redirectUrl);
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: true
});
var chatClient;
for (var i = 0; i < allClients.length; i++) {
var client = allClients[i];
if (client['url'].indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break;
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient;
}
}());
}
});
self.addEventListener("notificationclose", function (event) {
event.notification.close();
console.log('user has clicked notification close');
});
application.js file :
/// <reference path="scripts/jquery-3.3.1.js" />
try {
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push is supported');
navigator.serviceWorker
.register('/firebase-messaging-sw.js')
.then((swReg) => {
firebase.messaging().useServiceWorker(swReg);
askForPermissioToReceiveNotifications();
})
.catch(function (error) {
console.error('Service Worker Error', error);
window.alert("Service Worker Error" + error);
})
} else {
console.warn('Push messaging is not supported');
window.alert("Push messaging is not supported " + (navigator.serviceWorker));
}
const askForPermissioToReceiveNotifications = async () => {
try {
const messaging = firebase.messaging();
console.log(messaging);
await messaging.requestPermission();
const token = await messaging.getToken();
if (token !== null || token !== 'undefined') {
await sendDeviceTokenToServerSide(token);
}
console.log('Got token : ' + token);
messaging.onMessage(function (payload) {
console.log('onMessage: ', payload);
setTimeout(() => {
navigator.serviceWorker.ready.then(function (registration) {
var notificationTitle = payload.notification.title;
var notificationOptions = {
body: payload.notification.body,
data: payload.data,
icon: payload.notification.icon,
image: payload.data.Image,
requireInteraction: payload.notification.requireInteraction,
tag: payload.notification.tag,
click_action: payload.data.click_action,
requireInteraction: true
};
registration.showNotification(notificationTitle, notificationOptions);
},50)
});
});
}
catch (e) { console.log('error in getting token: ' + e); window.alert("error in getting token: " + e); }
}
function sendDeviceTokenToServerSide(token) {
$.ajax({
type: 'POST',
url: '/Home/StoreToken',
timeout: 5000000,
data: { token: token },
success: function (success) {
console.log("device token is sent to server");
},
error: function (error) {
console.log("device error sending token to server : " + error);
window.alert("device error sending token to server : " + error);
}
});
}
} catch (e) {
window.alert("error: " + e);
}
function GetFcmUserToken(messaging) {
messaging.onTokenRefresh(function () {
messaging.getToken()
.then(function (refreshedToken) {
console.log('Token refreshed.');
return refreshedToken;
})
.catch(function (err) {
console.log('Unable to retrieve refreshed token ', err);
showToken('Unable to retrieve refreshed token ', err);
});
});
}
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
// Do something as the result of the notification click
const promiseChain = clients.openWindow(clickedNotification.data.Url);
event.waitUntil(promiseChain);
});
This code inside service worker js worked fine for me on chrome Desktop and Android.

Socket.io - Refresh tokens before reconnect

I am creating an Electron app with Socket.io. When the user's computer goes into sleep mode the server disconnects from the client throwing an error "transport close". When the user tries to reconnect I check if the tokens are still valid, if they are not, I refresh them and try to send them to the socketIo server.
The problem I have is that on "reconnect_attempt" socket.io doesn't wait until I refresh the tokens to try reconnecting, it tries reconnecting right away with the old tokens, which get rejected by the server, which also seems to terminate the connection with the user impeding future reconnect attempts.
This is part of my code to connect to the server
module.exports.connect = async (JWT) => {
return new Promise( async resolve => {
console.log("connecting to the server")
const connectionOptions = {
secure: true,
query: {token: JWT},
reconnectionDelay: 4000
}
let socket = await socketIo.connect(`${process.env.SERVER_URL}:${process.env.SERVER_PORT}`, connectionOptions);
resolve(socket)
})
}
This is my code for reconnect_attempt
socket.on('reconnect_attempt', async () => {
const getCurrentJWT = require("../../main").getCurrentJWT;
let JWT = await getCurrentJWT(); //By the time this line returns, socket.io has already tried to reconnect
if(JWT.success) { //if refreshed successfully
console.log("Trying to submit new token......", JWT);
socket.query.token = JWT.JWT;
} else {
console.log("Token not refreshed.")
}
});
And this is part of what I have on the server
io.use(async (socket, next) => {
let token = socket.handshake.query.token;
//and the instruction from here https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html
let tokenIsValid = await checkTokenValidity(token);
if( tokenIsValid ) {
next();
} else {
next(new Error('invalidToken'));
console.log("Not valid token")
}
})
In short, you can use auth for this.
While connecting
auth: {
token: token
}
In the time of reconnection
socket.auth.token = "NEW_TOKEN";
socket.connect();
I can share socket io implementation for this and you can modify it as your need.
For the client-side,
let unauthorized = false;
let socket = io.connect('ws://localhost:8080', {
transports: ["websocket"],
auth: {
token: GET_YOUR_TOKEN()
}
});
socket.on("connect", () => {
unauthorized = false;
});
socket.on('UNAUTHORIZED', () => {
unauthorized = true;
});
socket.on("disconnect", (reason) => {
if (reason === "io server disconnect") {
if(unauthorized) {
socket.auth.token = token;
}
socket.connect();
}
});
socket.on('PING', ()=>{
socket.emit('PONG', token);
});
For the server-side
io.on("connection", (socket) => {
socket.on('PONG', function (token) {
if (isValidToken(token) == false) {
socket.emit("UNAUTHORIZED");
socket.disconnect();
}
});
setInterval(() => {
socket.emit('PING');
}, <YOUR-TIME>);
});
Having the following in your server.
io.use( async function(socket, next) {
let address = socket.handshake.address;
run++; // 0 -> 1
// Validate Token
const token = socket.handshake.auth.token;
if(token !== undefined){
try{
await tokenVerify(token).then((payload) => {
const serverTimestamp = Math.floor(Date.now() / 1000);
const clientTimestamp = payload.exp;
if(clientTimestamp > serverTimestamp){
console.log("Connection from: " + address + " was accepted");
console.log("Token [" + token + "] from: " + address + " was accepted");
next();
}else{
console.log("Connection from: " + address + " was rejected");
console.log("Token [" + token + "] from: " + address + " was rejected");
next(new Error("unauthorized"));
}
});
}catch (e) {
console.log(e);
}
}
})
With the code above, the server will respond "unauthorized" if the token isn't valid.
So, on the client-side, we can catch that message as shown below.
socket_io.on("connect_error", (err) => {
if(err?.message === 'unauthorized'){
var timeout = (socket_reconnection_attempts === 0 ? 5000 : 60000)
console.log("Trying to reconnect in the next " + (timeout / 1000) + ' seconds')
setTimeout(function (){
console.log('Trying to reconnect manually')
socket_reconnection_attempts++;
loadAuthToken().then(function (token) {
socket_io.auth.token = token;
socket_io.connect();
})
}, timeout)
}
});
With the code above, the client-side will try to reconnect and refresh the token only if the error message is "unauthorized."
The variable "socket_reconnection_attempts" is to avoid sending a massive number of reconnection attempts in a short period of time.

How to set right path on localhost

Hey Guys,
I have a problem to show my picture on my Page.
I dont know how to set the right path to show my picture.
I use socket.io and express. The Page is running on a Localhost Server
this is my code to show the picture but it doesnt works.
img src="uploads/images.png"
On the server-side i did this "app.use(express.static('public'));" to make it public. But it doesnt work, can someone help me ?
What is the right path?
My Folder structure is this
Folder structure
Server-side:
var app = require('express')();
var express = require('express');
var upload = require('express-fileupload');
var http = require('http').Server(app);
var io = require('socket.io')(http);
var multer = require('multer');
var fs = require('fs');
app.use(upload());
app.use(express.static('public'));
var users = {};
var allUsers = [];
function actualTime(){
var d = new Date();
return d.toLocaleTimeString();}
http.listen(3000, function(){
console.log('listening on *:3000');
});
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
app.post('/upload',function(req,res){
console.log(req.files);
if(req.files.upfile){
var file = req.files.upfile,
name = file.name,
type = file.mimetype;
var uploadpath = __dirname + '/uploads/' + name;
file.mv(uploadpath,function(err){
if(err){
console.log("File Upload Failed",name,err);
res.send("Error Occured!")
}
else {
console.log("File Uploaded",name);
console.log("guckmal");
io.emit('file', name);
res.send('sasa');
}
});
}
else {
res.send("No File selected !");
res.end();
};
})
socket.on('username', function(data,callback){
if(data in users || data.length<=2){
callback(false);
}else{
callback(true);
socket.nickname = data;
users[socket.nickname] = socket;
// to get a message for all users who are not in the priavte chat
allUsers.push(""+socket.nickname);
for(var test=0; test<allUsers.length;test++){
console.log(allUsers[test]);
users[allUsers[test]].emit('usernames', {list:Object.keys(users), nick: allUsers[test]});
}
io.emit('chat message',{msg:"joined the Chatroom", nick:socket.nickname, time:actualTime()});
}
});
socket.on('chat message', function(data, callback){
console.log(socket.nickname);
console.log('User: ' + socket.nickname + ' message: ' + data);
var msg = data.trim();
if(msg.substr(0,3)=== '/w '){
console.log("private chat");
msg= msg.substr(3);
var temp = msg.indexOf(' ');
if(temp !== -1){
console.log("private chat stap 2");
var name = msg.substring(0,temp);
var msg = msg.substring(temp+1);
if(name in users){
console.log("private chat stap 3");
users[name].emit('private chat', {msg:msg, nick:socket.nickname, time:actualTime()});
for(var i=0; i<allUsers.length;i++){
if((name !==allUsers[i])){
if(allUsers[i] !== socket.nickname){
users[allUsers[i]].emit('private chat',{msg:"private message was send from "+socket.nickname+" to "+name, nick:socket.nickname, time:actualTime()});
}else{
users[socket.nickname].emit('private chat',{msg:"you send a private messgae to "+name, nick:"chat", time:actualTime()});
}
}
}
}else{
callback(' user name doesnt exist');
}
}else{
callback('Error! Please enter a message');
}
}else{
io.emit('chat message', {msg:msg, nick:socket.nickname, time:actualTime()});
}
});
socket.on('disconnect', function(data){
delete users[socket.nickname];
io.emit('chat message',{msg:"leaved the Chatroom", nick:socket.nickname, time:actualTime()});
io.sockets.emit('usernames', {list:Object.keys(users)});
});
});
Client-side:
$(function () {
var socket = io();
$('#loginForm').submit(function(e){
e.preventDefault(); // prevents page reloading
socket.emit('username', $('#u').val(), function(data,callback){
if(data){
$('#nickWrap').hide();
$('#contentWrap').show();
}else if(($('#u').val()).length<=2){
document.getElementById("u").value="";
document.getElementById("u").placeholder ="Sorry but Username length is less then three :(";
}else{
document.getElementById("u").value="";
document.getElementById("u").placeholder ="Sorry but Username already taken :(";
}
});
});
$('#chatForm').submit(function(e){
e.preventDefault(); // prevents page reloading
if(privateUsers.length>0){
for(var i=0;i<privateUsers.length;i++){
socket.emit('chat message','/w '+ privateUsers[i] +' '+ $('#m').val(), function(data){
// add stuff later
$('#messages').append($('<li>').text(data.time + " " + data.nick +': '+ data.msg ));
});
}
}else{
socket.emit('chat message', $('#m').val(), function(data){
// add stuff later
$('#messages').append($('<li>').text(data.time + " " + data.nick+': '+ data.msg ));
});
}
$('#m').val('');
return false;
});
socket.on('chat message', function(data){
$('#messages').append($('<li>').text(data.time + " " + data.nick +': '+ data.msg ));
});
socket.on('file', function(data){
var img = document.getElementById('bild');
images.push[data];
var name = data;
console.log(name);
$('#messages').append('<li><img src="uploads/images.png" />'+ '</li>');
img.setAttribute('src','data:image/jpeg;base64,' + window.btoa(images));
});
socket.on('private chat', function(data){
$('#messages').append($('<li>').text(data.time + " " + data.nick +': '+ data.msg ));
});
socket.on('usernames', function(socket, data){
console.log("2222222222");
// to get a massage for all users who are not in the priavte chat
console.log(socket.nick);
socketName = socket.nick;
});
socket.on('usernames', function(data){
document.getElementById("userList").innerHTML = "";
var temp;
var indexTemp;
var me= "";
var sortData = [];
for(var i=0;i<data.list.length;i++){
if(data.nick === data.list[i]){
indexTemp = i;
/* temp = data.list[i];
indexTemp =i;
data.list[i]= "Ich";*/
me ="My Name: ";
}
}
// sort list
sortData.push(data.list[indexTemp]);
for(var l=0; l<data.list.length;l++){
if(indexTemp !=l){
sortData.push(data.list[l]);
}
}
for(var i =0; i<sortData.length;i++){
if(i==0){
$('#userList').append('<li style="list-style:none "><buttonid="'+sortData[i]+'" onclick='+'"addUsers()"'+
' style="width: 100%; background: rgb(130, 224, 255); border: none; padding:10%; margin-bottom:2%; "'+'>'+"My Name: "+ sortData[i]
+'</button></li>');
//data.list[i]= temp;
}else{
$('#userList').append('<li style="list-style:none "><button id="'+sortData[i]+'" onclick='+'"addUsers(\''+sortData[i]+'\')"'+
' style="width: 100%; background: rgb(130, 224, 255); border: none; padding:10%; margin-bottom:2%; "'+'>'+ sortData[i]
+'</button></li>');
}
}
// }
});
});
function addUsers(name){
if(privateUsers.length==0){
console.log("erstes objekt");
document.getElementById(name).style.background = "rgb(1, 254, 185)";
privateUsers.push(name);
}else{
for(var i=0;i<privateUsers.length;i++){
if(name==privateUsers[i]){
console.log("gel�scht");
document.getElementById(name).style.background = "rgb(130, 224, 255)";
privateUsers.splice(i,1);
return;
}
}
console.log("drinnen");
document.getElementById(name).style.background = "rgb(1, 254, 185)";
privateUsers.push(name);
}
}

ExpressJS Ajax request is getting redirected/Aborted

I'm trying to make an AJAX request to one of my routes which should return some data, but I can't solve the fact that when I make an AJAX request I'm being redirected to the route I'm requesting.
How can I prevent this from happening?
Ajax:
var request = new XMLHttpRequest();
var url = 'http://localhost:3000/signin';
var credentials = {
email: document.getElementsByName('email')[0].value,
password: document.getElementsByName('password')[0].value
};
JSON.stringify(credentials);
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE) {
if(request.status == 200) {
if(request.readyState == 4) {
var data = JSON.parse(request.responseText);
console.log(data);
}
} else if(request.status == 400) {
console.log('There was an error 400');
} else {
console.log('something else other than 200 was returned');
}
}
}
request.open('POST', url, true);
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(credentials);
Api Endpoint:
app.post('/signin', function(req, res) {
request.post({
url:'http://localhost:3000/api/authenticate',
form: {
email: req.body.email,
hashed_password: req.body.password
},
}, function(err, httpResponse, body) {
console.log(req.xhr);
console.log(req.headers);
if (err) {
return console.error('failed:', err);
}
console.log('successful! ', JSON.parse(body));
//user.token = data.token;
res.json(JSON.parse(body));
});
});

Can not connect with API , so couldn't retrieve post from db?

I got problem while I move into https://github.com/DaftMonk/generator-angular-fullstack.
Before my project was working. Here is code for frontend and backend part related to comment.
I am getting all time error 404. I don't know why I cannot find following path.
POST http://localhost:9000/api/providers/554a1dba53d9ca8c2a2a31ff/posts/554b1726f1116e00256e3d82/comments 404 (Not Found)
I am struggling couple of days to discover which part of my code have problem but I couldn't realize that.
server side
in comment.controller
// Creates a new comment in the DB.
exports.create = function(req, res) {
console.log('i ma inside api');
Post.findById(req.originalUrl.split('/')[3], function (err, post) { //here can not find post at all.
if (err) {
return handleError(res, err);
}
if (!post) {
return res.status(404).send('Post not found');
}
Comment.create(req.body, function (err, comment) {
if (err) {
return handleError(res, err);
}
post.comments.push(comment.id);
post.save(function (err) {
if (err) return handleError(res, err);
return res.status(201).json(comment);
});
});
});
};
route.js
app.use('/api/providers/:providerId/posts/:postId/comments', require('./api/provider/post/comment'));
index.js
var controller = require('./comment.controller.js');
var router = express.Router();
router.get('/', controller.index);
router.get('/:id', controller.show);
router.post('/', controller.create);
router.put('/:id', controller.update);
router.patch('/:id', controller.update);
router.delete('/:id', controller.destroy);
router.put('/:id/upvote', controller.upvote);
in client side:
factory:
//create new comment for post
ob.createComment = function(providerId, postId,comment) {
console.log('i am inside factory');
return $http.post('/api/providers/'+ providerId + '/posts/' + postId + '/comments' ,comment, {
headers: {Authorization: 'Bearer '+Auth.getToken()}
}).success(function(data){
_.forEach(ob.provider.posts,function(value,index){
if(value._id === post._id){
ob.posts[index].comments.push(data);
}
})
ob.current.comments.push(data)
// ob.provider1._id.posts.push(data);
});
};
in my controller
$scope.addComment = function(){
// if(!$scope.title || $scope.title === '') { return; }
if(!$scope.body || $scope.body === '') { return; }
console.log('$stateParams',$stateParams);
providers.createComment($stateParams.providerId, $stateParams.postId,{
//title: $scope.title,
body: $scope.body
});
$scope.body = '';
$scope.title = '';
};
This is my model in whole the project.

Resources