Merge branch 'hotfix/21.56.9' into master
[gitter.git] / modules / rooms / lib / recent-room-core.js
bloba6fff3eee34584a52b3a494a508fee8cebcb11a4
1 'use strict';
3 var Promise = require('bluebird');
4 var persistence = require('gitter-web-persistence');
5 var _ = require('lodash');
6 var debug = require('debug')('gitter:app:recent-room-core');
8 /* const */
9 var DEFAULT_LAST_ACCESS_TIME = new Date('2015-07-01T00:00:00Z');
11 function clearLastVisitedTroupeforUserId(userId, troupeId) {
12   debug('recent-rooms: Clearing last visited Troupe for user: %s to troupe %s', userId, troupeId);
14   var setOp = {};
15   setOp['troupes.' + troupeId] = 1;
17   // Update UserTroupeLastAccess
18   return persistence.UserTroupeLastAccess.update(
19     { userId: userId },
20     { $unset: setOp },
21     { upsert: true, new: true }
22   ).exec();
25 /**
26  * Returns Promise of true if an update actually happened
27  */
28 function saveUserTroupeLastAccess(userId, troupeId, lastAccessTime) {
29   if (lastAccessTime) {
30     if (!(lastAccessTime instanceof Date)) {
31       lastAccessTime = new Date(lastAccessTime);
32     }
33   } else {
34     lastAccessTime = new Date();
35   }
37   var maxOp = {};
38   maxOp['troupes.' + troupeId] = lastAccessTime;
39   maxOp['last.' + troupeId] = lastAccessTime;
41   return persistence.UserTroupeLastAccess.update(
42     { userId: userId },
43     { $max: maxOp },
44     { upsert: true }
45   )
46     .lean(true)
47     .exec()
48     .then(function(result) {
49       return !!(result.nModified || (result.upserted && result.upserted.length));
50     });
53 function getTroupeLastAccessTimesForUserExcludingHidden(userId) {
54   return persistence.UserTroupeLastAccess.findOne(
55     { userId: userId },
56     { _id: 0, troupes: 1 },
57     { lean: true }
58   )
59     .exec()
60     .then(function(userTroupeLastAccess) {
61       if (!userTroupeLastAccess || !userTroupeLastAccess.troupes) return {};
62       return userTroupeLastAccess.troupes;
63     });
66 /**
67  * Get the last access times for a user.
68  * @param userId user we're getting the last access time for
69  * @return promise of a hash of { troupeId1: accessDate, troupeId2: accessDate ... }
70  */
71 function getTroupeLastAccessTimesForUser(userId) {
72   return persistence.UserTroupeLastAccess.findOne(
73     { userId: userId },
74     { _id: 0, last: 1, troupes: 1 },
75     { lean: true }
76   )
77     .exec()
78     .then(function(userTroupeLastAccess) {
79       if (!userTroupeLastAccess) return {};
81       // Merge the results from `last` and `troupe`, giving priority to
82       // the values from last
83       return _.extend({}, userTroupeLastAccess.troupes, userTroupeLastAccess.last);
84     });
87 /**
88  * Returns a hash of the last access times for an array of userIds for a given room.
89  * If the user has never accessed the room, the value will represent the
90  * date the user was added to the room, or the date this feature was deployed
91  * as a default ~1 July 2015.
92  */
93 function findLastAccessTimesForUsersInRoom(roomId, userIds) {
94   if (!userIds.length) return Promise.resolve({});
96   var troupesKey = 'troupes.' + roomId;
97   var lastKey = 'last.' + roomId;
98   var addedKey = 'added.' + roomId;
100   var orClause = [{}, {}, {}];
101   orClause[0][troupesKey] = { $exists: true };
102   orClause[1][lastKey] = { $exists: true };
103   orClause[2][addedKey] = { $exists: true };
105   var query = { userId: { $in: userIds }, $or: orClause };
107   var select = { userId: 1, _id: 0 };
108   select[troupesKey] = 1;
109   select[lastKey] = 1;
110   select[addedKey] = 1;
112   return persistence.UserTroupeLastAccess.find(query, select, { lean: true })
113     .exec()
114     .then(function(lastAccessTimes) {
115       var lastAccessTimesHash = lastAccessTimes.reduce(function(memo, item) {
116         // Use the last date by default, falling back to the troupes hash for
117         // backwards compatibility
118         memo[item.userId] =
119           (item.last && item.last[roomId]) ||
120           (item.troupes && item.troupes[roomId]) ||
121           (item.added && item.added[roomId]);
122         return memo;
123       }, {});
125       return userIds.reduce(function(memo, userId) {
126         memo[userId] = lastAccessTimesHash[userId] || DEFAULT_LAST_ACCESS_TIME;
127         return memo;
128       }, {});
129     });
132 module.exports = {
133   saveUserTroupeLastAccess,
134   getTroupeLastAccessTimesForUserExcludingHidden,
135   getTroupeLastAccessTimesForUser,
136   findLastAccessTimesForUsersInRoom,
137   clearLastVisitedTroupeforUserId