3 var env = require('gitter-web-env');
4 var logger = env.logger;
6 var Promise = require('bluebird');
7 var StatusError = require('statuserror');
8 var gitHubProfileService = require('gitter-web-github-backend/lib/github-profile-service');
9 var groupService = require('gitter-web-groups/lib/group-service');
10 var groupMembershipService = require('gitter-web-groups/lib/group-membership-service');
11 var restSerializer = require('../serializers/rest-serializer');
12 var unreadItemService = require('gitter-web-unread-items');
13 var chatService = require('gitter-web-chats');
14 var userService = require('gitter-web-users');
15 var userTypeahead = require('./typeaheads/user-typeahead');
16 var eventService = require('gitter-web-events');
17 var roomService = require('gitter-web-rooms');
18 var roomMembershipService = require('gitter-web-rooms/lib/room-membership-service');
19 var orgService = require('./org-service');
20 var repoService = require('./repo-service');
21 var userScopes = require('gitter-web-identity/lib/user-scopes');
23 var survivalMode = !!process.env.SURVIVAL_MODE || false;
26 logger.error('WARNING: Running in survival mode');
29 var DEFAULT_CHAT_COUNT_LIMIT = 30;
30 var DEFAULT_USERS_LIMIT = 30;
31 var MAX_USERS_LIMIT = 100;
33 function serializeTroupesForUser(userId, callback) {
34 if (!userId) return Promise.resolve([]);
37 .findAllRoomsIdsForUserIncludingMentions(userId)
38 .spread(function(allTroupeIds, nonMemberTroupeIds) {
39 var strategy = new restSerializer.TroupeIdStrategy({
40 currentUserId: userId,
41 includePermissions: true,
42 // This will save the troupeId strategy
43 // from having to do a second query
44 nonMemberTroupeIds: nonMemberTroupeIds,
48 return restSerializer.serialize(allTroupeIds, strategy);
53 async function serializeChatsForTroupe(
56 { limit = DEFAULT_CHAT_COUNT_LIMIT, lean, aroundId, lookups, beforeInclId, includeThreads }
58 const chatMessages = await chatService.findChatMessagesForTroupe(troupeId, {
64 const strategy = new restSerializer.ChatStrategy({
67 currentUserId: userId,
72 return restSerializer.serialize(chatMessages, strategy);
75 function serializeUsersMatchingSearchTerm(roomId, searchTerm) {
76 if (survivalMode || searchTerm.length < 1) {
77 return Promise.resolve([]);
80 return userTypeahead.query(searchTerm, { roomId }).then(function(users) {
81 const strategy = new restSerializer.UserStrategy();
82 return restSerializer.serialize(users, strategy);
88 * @param {*} options Options can be:
89 * - `limit` - maximum amount of records retrieved
90 * - `lean` - if true, the result is not full mongoose model, just plain object
91 * - `skip` - how many first records should be omitted (used for pagination)
93 function serializeUsersForTroupe(troupeId, userId, { limit, lean, skip }) {
94 limit = isNaN(limit) ? DEFAULT_USERS_LIMIT : limit;
95 skip = isNaN(skip) ? 0 : skip;
96 if (limit > MAX_USERS_LIMIT) {
97 limit = MAX_USERS_LIMIT;
99 return roomMembershipService
100 .findMembersForRoom(troupeId, { limit, skip })
101 .then(function(userIds) {
102 var strategy = new restSerializer.UserIdStrategy({
103 showPresenceForTroupeId: troupeId,
104 includeRolesForTroupeId: troupeId,
105 currentUserId: userId,
109 return restSerializer.serialize(userIds, strategy);
113 function serializeUnreadItemsForTroupe(troupeId, userId, callback) {
115 roomMembershipService.getMemberLurkStatus(troupeId, userId),
116 unreadItemService.getUnreadItemsForUser(userId, troupeId)
118 .spread(function(isLurking, items) {
120 items._meta = { lurk: true };
127 function serializeReadBysForChat(troupeId, chatId, callback) {
128 // TODO: assert that troupeId=chat.troupeId....
131 .then(function(chatMessage) {
132 var strategy = new restSerializer.UserIdStrategy({});
134 return restSerializer.serialize(chatMessage.readBy, strategy);
139 function serializeEventsForTroupe(troupeId, userId, callback) {
141 .findEventsForTroupe(troupeId, {})
142 .then(function(events) {
143 var strategy = new restSerializer.EventStrategy({
144 currentUserId: userId,
147 return restSerializer.serialize(events, strategy);
152 async function serializeOrgsForUser(user) {
153 const orgs = await orgService.getOrgsForUser(user);
155 const strategyMap = {
156 gitlab: new restSerializer.GitlabGroupStrategy(),
157 github: new restSerializer.GithubOrgStrategy({
158 currentUserId: user && user._id
162 const serializeOrgPromises = orgs.map(org => {
163 const strategy = strategyMap[org.backend];
165 return restSerializer.serializeObject(org, strategy);
168 const serializedOrgs = await Promise.all(serializeOrgPromises);
169 return serializedOrgs;
172 function serializeOrgsForUserId(userId, options) {
173 return userService.findById(userId).then(function(user) {
174 if (!user) return [];
176 return serializeOrgsForUser(user, options);
180 async function _serializeReposForUser(user, repos) {
181 const strategyMap = {
182 gitlab: new restSerializer.GitlabProjectStrategy(),
183 github: new restSerializer.GithubRepoStrategy({
184 currentUserId: user && user._id
188 const serializeRepoPromises = repos.map(repo => {
189 const strategy = strategyMap[repo.backend];
191 return restSerializer.serializeObject(repo, strategy);
194 const serializedRepos = await Promise.all(serializeRepoPromises);
195 return serializedRepos;
198 async function serializeReposForUser(user) {
199 const repos = await repoService.getReposForUser(user);
200 return _serializeReposForUser(user, repos);
203 async function serializeAdminReposForUser(user) {
204 const repos = await repoService.getAdminReposForUser(user);
205 return _serializeReposForUser(user, repos);
208 function serializeProfileForUsername(username) {
209 return userService.findByUsername(username).then(function(user) {
211 var strategy = new restSerializer.UserProfileStrategy();
212 return restSerializer.serializeObject(user, strategy);
214 var gitHubUser = { username: username };
216 if (!userScopes.isGitHubUser(gitHubUser)) {
217 throw new StatusError(404);
220 return gitHubProfileService(gitHubUser, { includeCore: true });
225 function serializeGroupsForUserId(userId, options) {
226 if (!userId) return [];
228 return groupMembershipService.findGroupsForUser(userId).then(function(groups) {
229 if (!groups || !groups.length) return [];
231 var strategy = new restSerializer.GroupStrategy({
232 currentUserId: userId,
233 lean: options && options.lean
236 return restSerializer.serialize(groups, strategy);
240 function serializeAdminGroupsForUser(user, options) {
241 if (!user) return [];
243 return groupMembershipService.findAdminGroupsForUser(user).then(function(groups) {
244 if (!groups || !groups.length) return [];
246 var strategy = new restSerializer.GroupStrategy({
247 currentUserId: user._id,
249 lean: options && options.lean
252 return restSerializer.serialize(groups, strategy);
256 function serializeRoomsForGroupId(groupId, userId) {
257 return groupService.findRoomsIdForGroup(groupId, userId).then(function(allTroupeIds) {
258 var strategy = new restSerializer.TroupeIdStrategy({
259 currentUserId: userId
262 return restSerializer.serialize(allTroupeIds, strategy);
267 serializeTroupesForUser: serializeTroupesForUser,
268 serializeChatsForTroupe: serializeChatsForTroupe,
269 serializeUsersForTroupe: serializeUsersForTroupe,
270 serializeUsersMatchingSearchTerm: serializeUsersMatchingSearchTerm,
271 serializeUnreadItemsForTroupe: serializeUnreadItemsForTroupe,
272 serializeReadBysForChat: serializeReadBysForChat,
273 serializeEventsForTroupe: serializeEventsForTroupe,
274 serializeOrgsForUser: serializeOrgsForUser,
275 serializeOrgsForUserId: serializeOrgsForUserId,
276 serializeReposForUser: serializeReposForUser,
277 serializeAdminReposForUser: serializeAdminReposForUser,
278 serializeProfileForUsername: serializeProfileForUsername,
279 serializeGroupsForUserId: Promise.method(serializeGroupsForUserId),
280 serializeAdminGroupsForUser: Promise.method(serializeAdminGroupsForUser),
281 serializeRoomsForGroupId: serializeRoomsForGroupId