The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/packages/rocketchat-lib/server/models/Subscriptions.js

850 lines
14 KiB

import { Match } from 'meteor/check';
class ModelSubscriptions extends RocketChat.models._Base {
constructor(...args) {
super(...args);
this.tryEnsureIndex({ rid: 1, 'u._id': 1 }, { unique: 1 });
this.tryEnsureIndex({ rid: 1, 'u.username': 1 });
this.tryEnsureIndex({ rid: 1, alert: 1, 'u._id': 1 });
this.tryEnsureIndex({ rid: 1, roles: 1 });
this.tryEnsureIndex({ 'u._id': 1, name: 1, t: 1 });
this.tryEnsureIndex({ open: 1 });
this.tryEnsureIndex({ alert: 1 });
this.tryEnsureIndex({ rid: 1, 'u._id': 1, open: 1 });
this.tryEnsureIndex({ ts: 1 });
this.tryEnsureIndex({ ls: 1 });
this.tryEnsureIndex({ audioNotifications: 1 }, { sparse: 1 });
this.tryEnsureIndex({ desktopNotifications: 1 }, { sparse: 1 });
this.tryEnsureIndex({ mobilePushNotifications: 1 }, { sparse: 1 });
this.tryEnsureIndex({ emailNotifications: 1 }, { sparse: 1 });
this.tryEnsureIndex({ autoTranslate: 1 }, { sparse: 1 });
this.tryEnsureIndex({ autoTranslateLanguage: 1 }, { sparse: 1 });
this.tryEnsureIndex({ 'userHighlights.0': 1 }, { sparse: 1 });
}
// FIND ONE
findOneByRoomIdAndUserId(roomId, userId, options) {
const query = {
rid: roomId,
'u._id': userId,
};
return this.findOne(query, options);
}
findOneByRoomIdAndUsername(roomId, username, options) {
const query = {
rid: roomId,
'u.username': username,
};
return this.findOne(query, options);
}
findOneByRoomNameAndUserId(roomName, userId) {
const query = {
name: roomName,
'u._id': userId,
};
return this.findOne(query);
}
// FIND
findByUserId(userId, options) {
const query =
{ 'u._id': userId };
return this.find(query, options);
}
findByUserIdAndType(userId, type, options) {
const query = {
'u._id': userId,
t: type,
};
return this.find(query, options);
}
findByUserIdAndTypes(userId, types, options) {
const query = {
'u._id': userId,
t: {
$in: types,
},
};
return this.find(query, options);
}
findByUserIdUpdatedAfter(userId, updatedAt, options) {
const query = {
'u._id': userId,
_updatedAt: {
$gt: updatedAt,
},
};
return this.find(query, options);
}
findByRoomIdAndRoles(roomId, roles, options) {
roles = [].concat(roles);
const query = {
rid: roomId,
roles: { $in: roles },
};
return this.find(query, options);
}
findByType(types, options) {
const query = {
t: {
$in: types,
},
};
return this.find(query, options);
}
findByTypeAndUserId(type, userId, options) {
const query = {
t: type,
'u._id': userId,
};
return this.find(query, options);
}
findByRoomId(roomId, options) {
const query =
{ rid: roomId };
return this.find(query, options);
}
findByRoomIdAndNotUserId(roomId, userId, options) {
const query = {
rid: roomId,
'u._id': {
$ne: userId,
},
};
return this.find(query, options);
}
findByRoomWithUserHighlights(roomId, options) {
const query = {
rid: roomId,
'userHighlights.0': { $exists: true },
};
return this.find(query, options);
}
getLastSeen(options) {
if (options == null) {
options = {};
}
const query = { ls: { $exists: 1 } };
options.sort = { ls: -1 };
options.limit = 1;
const [subscription] = this.find(query, options).fetch();
return subscription && subscription.ls;
}
findByRoomIdAndUserIds(roomId, userIds, options) {
const query = {
rid: roomId,
'u._id': {
$in: userIds,
},
};
return this.find(query, options);
}
findByRoomIdAndUserIdsOrAllMessages(roomId, userIds) {
const query = {
rid: roomId,
$or: [
{ 'u._id': { $in: userIds } },
{ emailNotifications: 'all' },
],
};
return this.find(query);
}
findByRoomIdWhenUserIdExists(rid, options) {
const query = { rid, 'u._id': { $exists: 1 } };
return this.find(query, options);
}
findByRoomIdWhenUsernameExists(rid, options) {
const query = { rid, 'u.username': { $exists: 1 } };
return this.find(query, options);
}
findUnreadByUserId(userId) {
const query = {
'u._id': userId,
unread: {
$gt: 0,
},
};
return this.find(query, { fields: { unread: 1 } });
}
getMinimumLastSeenByRoomId(rid) {
return this.db.findOne({
rid,
}, {
sort: {
ls: 1,
},
fields: {
ls: 1,
},
});
}
// UPDATE
archiveByRoomId(roomId) {
const query =
{ rid: roomId };
const update = {
$set: {
alert: false,
open: false,
archived: true,
},
};
return this.update(query, update, { multi: true });
}
unarchiveByRoomId(roomId) {
const query =
{ rid: roomId };
const update = {
$set: {
alert: false,
open: true,
archived: false,
},
};
return this.update(query, update, { multi: true });
}
hideByRoomIdAndUserId(roomId, userId) {
const query = {
rid: roomId,
'u._id': userId,
};
const update = {
$set: {
alert: false,
open: false,
},
};
return this.update(query, update);
}
openByRoomIdAndUserId(roomId, userId) {
const query = {
rid: roomId,
'u._id': userId,
};
const update = {
$set: {
open: true,
},
};
return this.update(query, update);
}
setAsReadByRoomIdAndUserId(roomId, userId) {
const query = {
rid: roomId,
'u._id': userId,
};
const update = {
$set: {
open: true,
alert: false,
unread: 0,
userMentions: 0,
groupMentions: 0,
ls: new Date,
},
};
return this.update(query, update);
}
setAsUnreadByRoomIdAndUserId(roomId, userId, firstMessageUnreadTimestamp) {
const query = {
rid: roomId,
'u._id': userId,
};
const update = {
$set: {
open: true,
alert: true,
ls: firstMessageUnreadTimestamp,
},
};
return this.update(query, update);
}
setCustomFieldsDirectMessagesByUserId(userId, fields) {
const query = {
'u._id': userId,
t: 'd',
};
const update = { $set: { customFields: fields } };
const options = { multi: true };
return this.update(query, update, options);
}
setFavoriteByRoomIdAndUserId(roomId, userId, favorite) {
if (favorite == null) {
favorite = true;
}
const query = {
rid: roomId,
'u._id': userId,
};
const update = {
$set: {
f: favorite,
},
};
return this.update(query, update);
}
updateNameAndAlertByRoomId(roomId, name, fname) {
const query =
{ rid: roomId };
const update = {
$set: {
name,
fname,
alert: true,
},
};
return this.update(query, update, { multi: true });
}
updateDisplayNameByRoomId(roomId, fname) {
const query =
{ rid: roomId };
const update = {
$set: {
fname,
},
};
return this.update(query, update, { multi: true });
}
setUserUsernameByUserId(userId, username) {
const query =
{ 'u._id': userId };
const update = {
$set: {
'u.username': username,
},
};
return this.update(query, update, { multi: true });
}
setNameForDirectRoomsWithOldName(oldName, name) {
const query = {
name: oldName,
t: 'd',
};
const update = {
$set: {
name,
},
};
return this.update(query, update, { multi: true });
}
incUnreadForRoomIdExcludingUserId(roomId, userId, inc) {
if (inc == null) {
inc = 1;
}
const query = {
rid: roomId,
'u._id': {
$ne: userId,
},
};
const update = {
$set: {
alert: true,
open: true,
},
$inc: {
unread: inc,
},
};
return this.update(query, update, { multi: true });
}
incGroupMentionsAndUnreadForRoomIdExcludingUserId(roomId, userId, incGroup = 1, incUnread = 1) {
const query = {
rid: roomId,
'u._id': {
$ne: userId,
},
};
const update = {
$set: {
alert: true,
open: true,
},
$inc: {
unread: incUnread,
groupMentions: incGroup,
},
};
return this.update(query, update, { multi: true });
}
incUserMentionsAndUnreadForRoomIdAndUserIds(roomId, userIds, incUser = 1, incUnread = 1) {
const query = {
rid: roomId,
'u._id': {
$in: userIds,
},
};
const update = {
$set: {
alert: true,
open: true,
},
$inc: {
unread: incUnread,
userMentions: incUser,
},
};
return this.update(query, update, { multi: true });
}
ignoreUser({ _id, ignoredUser : ignored, ignore = true }) {
const query = {
_id,
};
const update = {
};
if (ignore) {
update.$addToSet = { ignored };
} else {
update.$pull = { ignored };
}
return this.update(query, update);
}
setAlertForRoomIdExcludingUserId(roomId, userId) {
const query = {
rid: roomId,
'u._id': {
$ne: userId,
},
alert: { $ne: true },
};
const update = {
$set: {
alert: true,
},
};
return this.update(query, update, { multi: true });
}
setOpenForRoomIdExcludingUserId(roomId, userId) {
const query = {
rid: roomId,
'u._id': {
$ne: userId,
},
open: { $ne: true },
};
const update = {
$set: {
open: true,
},
};
return this.update(query, update, { multi: true });
}
setBlockedByRoomId(rid, blocked, blocker) {
const query = {
rid,
'u._id': blocked,
};
const update = {
$set: {
blocked: true,
},
};
const query2 = {
rid,
'u._id': blocker,
};
const update2 = {
$set: {
blocker: true,
},
};
return this.update(query, update) && this.update(query2, update2);
}
unsetBlockedByRoomId(rid, blocked, blocker) {
const query = {
rid,
'u._id': blocked,
};
const update = {
$unset: {
blocked: 1,
},
};
const query2 = {
rid,
'u._id': blocker,
};
const update2 = {
$unset: {
blocker: 1,
},
};
return this.update(query, update) && this.update(query2, update2);
}
updateCustomFieldsByRoomId(rid, cfields) {
const query = { rid };
const customFields = cfields || {};
const update = {
$set: {
customFields,
},
};
return this.update(query, update, { multi: true });
}
updateTypeByRoomId(roomId, type) {
const query =
{ rid: roomId };
const update = {
$set: {
t: type,
},
};
return this.update(query, update, { multi: true });
}
addRoleById(_id, role) {
const query =
{ _id };
const update = {
$addToSet: {
roles: role,
},
};
return this.update(query, update);
}
removeRoleById(_id, role) {
const query =
{ _id };
const update = {
$pull: {
roles: role,
},
};
return this.update(query, update);
}
setArchivedByUsername(username, archived) {
const query = {
t: 'd',
name: username,
};
const update = {
$set: {
archived,
},
};
return this.update(query, update, { multi: true });
}
clearDesktopNotificationUserPreferences(userId) {
const query = {
'u._id': userId,
desktopPrefOrigin: 'user',
};
const update = {
$unset: {
desktopNotifications: 1,
desktopPrefOrigin: 1,
},
};
return this.update(query, update, { multi: true });
}
updateDesktopNotificationUserPreferences(userId, desktopNotifications) {
const query = {
'u._id': userId,
desktopPrefOrigin: {
$ne: 'subscription',
},
};
const update = {
$set: {
desktopNotifications,
desktopPrefOrigin: 'user',
},
};
return this.update(query, update, { multi: true });
}
clearMobileNotificationUserPreferences(userId) {
const query = {
'u._id': userId,
mobilePrefOrigin: 'user',
};
const update = {
$unset: {
mobilePushNotifications: 1,
mobilePrefOrigin: 1,
},
};
return this.update(query, update, { multi: true });
}
updateMobileNotificationUserPreferences(userId, mobilePushNotifications) {
const query = {
'u._id': userId,
mobilePrefOrigin: {
$ne: 'subscription',
},
};
const update = {
$set: {
mobilePushNotifications,
mobilePrefOrigin: 'user',
},
};
return this.update(query, update, { multi: true });
}
clearEmailNotificationUserPreferences(userId) {
const query = {
'u._id': userId,
emailPrefOrigin: 'user',
};
const update = {
$unset: {
emailNotifications: 1,
emailPrefOrigin: 1,
},
};
return this.update(query, update, { multi: true });
}
updateEmailNotificationUserPreferences(userId, emailNotifications) {
const query = {
'u._id': userId,
emailPrefOrigin: {
$ne: 'subscription',
},
};
const update = {
$set: {
emailNotifications,
emailPrefOrigin: 'user',
},
};
return this.update(query, update, { multi: true });
}
updateUserHighlights(userId, userHighlights) {
const query = {
'u._id': userId,
};
const update = {
$set: {
userHighlights,
},
};
return this.update(query, update, { multi: true });
}
updateDirectFNameByName(name, fname) {
const query = {
t: 'd',
name,
};
const update = {
$set: {
fname,
},
};
return this.update(query, update, { multi: true });
}
// INSERT
createWithRoomAndUser(room, user, extraData) {
const subscription = {
open: false,
alert: false,
unread: 0,
userMentions: 0,
groupMentions: 0,
ts: room.ts,
rid: room._id,
name: room.name,
fname: room.fname,
customFields: room.customFields,
t: room.t,
u: {
_id: user._id,
username: user.username,
name: user.name,
},
...RocketChat.getDefaultSubscriptionPref(user),
...extraData,
};
const result = this.insert(subscription);
RocketChat.models.Rooms.incUsersCountById(room._id);
return result;
}
// REMOVE
removeByUserId(userId) {
const query = {
'u._id': userId,
};
const roomIds = this.findByUserId(userId).map((s) => s.rid);
const result = this.remove(query);
if (Match.test(result, Number) && result > 0) {
RocketChat.models.Rooms.incUsersCountByIds(roomIds, -1);
}
return result;
}
removeByRoomId(roomId) {
const query = {
rid: roomId,
};
const result = this.remove(query);
if (Match.test(result, Number) && result > 0) {
RocketChat.models.Rooms.incUsersCountById(roomId, - result);
}
return result;
}
removeByRoomIdAndUserId(roomId, userId) {
const query = {
rid: roomId,
'u._id': userId,
};
const result = this.remove(query);
if (Match.test(result, Number) && result > 0) {
RocketChat.models.Rooms.incUsersCountById(roomId, - result);
}
return result;
}
}
RocketChat.models.Subscriptions = new ModelSubscriptions('subscription', true);