From d140a140de7d872a23376aa59a8495137742c3d1 Mon Sep 17 00:00:00 2001
From: Wu Cheng-Han <jacky_cute0808@hotmail.com>
Date: Tue, 20 Dec 2016 20:33:46 +0800
Subject: [PATCH] Fix possible user is undefined in realtime events

---
 lib/realtime.js | 43 ++++++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 17 deletions(-)

diff --git a/lib/realtime.js b/lib/realtime.js
index ed36a24fc..64b0044fa 100644
--- a/lib/realtime.js
+++ b/lib/realtime.js
@@ -211,6 +211,7 @@ function getStatus(callback) {
         var distinctregaddresses = [];
         Object.keys(users).forEach(function (key) {
             var user = users[key];
+            if (!user) return;
             var found = false;
             for (var i = 0; i < distinctaddresses.length; i++) {
                 if (user.address == distinctaddresses[i]) {
@@ -306,8 +307,9 @@ function emitOnlineUsers(socket) {
 
 function emitUserStatus(socket) {
     var noteId = socket.noteId;
-    if (!noteId || !notes[noteId]) return;
-    var out = buildUserOutData(users[socket.id]);
+    var user = users[socket.id];
+    if (!noteId || !notes[noteId] || !user) return;
+    var out = buildUserOutData(user);
     socket.broadcast.to(noteId).emit('user status', out);
 }
 
@@ -532,7 +534,9 @@ function disconnect(socket) {
     var note = notes[noteId];
     if (note) {
         // delete user in users
-        delete note.users[socket.id];
+        if (note.users[socket.id]) {
+            delete note.users[socket.id];
+        }
         // remove sockets in the note socks
         do {
             var index = note.socks.indexOf(socket);
@@ -649,14 +653,14 @@ function operationCallback(socket, operation) {
     var userId = null;
     // save authors
     if (socket.request.user && socket.request.user.logged_in) {
-        var socketId = socket.id;
-        var user = users[socketId]; 
+        var user = users[socket.id];
+        if (!user) return;
         userId = socket.request.user.id;
         if (!note.authors[userId]) {
             models.Author.create({
                 noteId: noteId,
                 userId: userId,
-                color: users[socketId].color
+                color: user.color
             }).then(function (author) {
                 note.authors[author.userId] = {
                     userid: author.userId,
@@ -743,11 +747,11 @@ function connection(socket) {
     //received user status
     socket.on('user status', function (data) {
         var noteId = socket.noteId;
-        if (!noteId || !notes[noteId]) return;
+        var user = users[socket.id];
+        if (!noteId || !notes[noteId] || !user) return;
         if (config.debug)
             logger.info('SERVER received [' + noteId + '] user status from [' + socket.id + ']: ' + JSON.stringify(data));
         if (data) {
-            var user = users[socket.id];
             user.idle = data.idle;
             user.type = data.type;
         }
@@ -840,7 +844,9 @@ function connection(socket) {
         logger.info('user changed');
         var noteId = socket.noteId;
         if (!noteId || !notes[noteId]) return;
-        updateUserData(socket, notes[noteId].users[socket.id]);
+        var user = notes[noteId].users[socket.id];
+        if (!user) return;
+        updateUserData(socket, user);
         emitOnlineUsers(socket);
     });
 
@@ -872,26 +878,29 @@ function connection(socket) {
     //received cursor focus
     socket.on('cursor focus', function (data) {
         var noteId = socket.noteId;
-        if (!noteId || !notes[noteId]) return;
-        users[socket.id].cursor = data;
-        var out = buildUserOutData(users[socket.id]);
+        var user = users[socket.id];
+        if (!noteId || !notes[noteId] || !user) return;
+        user.cursor = data;
+        var out = buildUserOutData(user);
         socket.broadcast.to(noteId).emit('cursor focus', out);
     });
 
     //received cursor activity
     socket.on('cursor activity', function (data) {
         var noteId = socket.noteId;
-        if (!noteId || !notes[noteId]) return;
-        users[socket.id].cursor = data;
-        var out = buildUserOutData(users[socket.id]);
+        var user = users[socket.id];
+        if (!noteId || !notes[noteId] || !user) return;
+        user.cursor = data;
+        var out = buildUserOutData(user);
         socket.broadcast.to(noteId).emit('cursor activity', out);
     });
 
     //received cursor blur
     socket.on('cursor blur', function () {
         var noteId = socket.noteId;
-        if (!noteId || !notes[noteId]) return;
-        users[socket.id].cursor = null;
+        var user = users[socket.id];
+        if (!noteId || !notes[noteId] || !user) return;
+        user.cursor = null;
         var out = {
             id: socket.id
         };