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/Rooms.js

791 lines
13 KiB

class ModelRooms extends RocketChat.models._Base {
constructor() {
super(...arguments);
this.tryEnsureIndex({ 'name': 1 }, { unique: 1, sparse: 1 });
this.tryEnsureIndex({ 'default': 1 });
this.tryEnsureIndex({ 'usernames': 1 });
this.tryEnsureIndex({ 't': 1 });
this.tryEnsureIndex({ 'u._id': 1 });
this.cache.ignoreUpdatedFields.push('msgs', 'lm');
this.cache.ensureIndex(['t', 'name'], 'unique');
this.cache.options = {fields: {usernames: 0}};
}
findOneByIdOrName(_idOrName, options) {
const query = {
$or: [{
_id: _idOrName
}, {
name: _idOrName
}]
};
return this.findOne(query, options);
}
findOneByImportId(_id, options) {
const query = {importIds: _id};
return this.findOne(query, options);
}
findOneByName(name, options) {
const query = {name};
return this.findOne(query, options);
}
findOneByNameAndNotId(name, rid) {
const query = {
_id: { $ne: rid },
name
};
return this.findOne(query);
}
findOneByDisplayName(fname, options) {
const query = {fname};
return this.findOne(query, options);
}
findOneByNameAndType(name, type, options) {
const query = {
name,
t: type
};
return this.findOne(query, options);
}
findOneByIdContainingUsername(_id, username, options) {
const query = {
_id,
usernames: username
};
return this.findOne(query, options);
}
findOneByNameAndTypeNotContainingUsername(name, type, username, options) {
const query = {
name,
t: type,
usernames: {
$ne: username
}
};
return this.findOne(query, options);
}
// FIND
findById(roomId, options) {
return this.find({ _id: roomId }, options);
}
findByIds(roomIds, options) {
return this.find({ _id: {$in: [].concat(roomIds)} }, options);
}
findByType(type, options) {
const query = {t: type};
return this.find(query, options);
}
findByTypes(types, options) {
const query = {
t: {
$in: types
}
};
return this.find(query, options);
}
findByUserId(userId, options) {
const query = {'u._id': userId};
return this.find(query, options);
}
findBySubscriptionUserId(userId, options) {
let data;
if (this.useCache) {
data = RocketChat.models.Subscriptions.findByUserId(userId).fetch();
data = data.map(function(item) {
if (item._room) {
return item._room;
}
console.log('Empty Room for Subscription', item);
return {};
});
return this.arrayToCursor(this.processQueryOptionsOnResult(data, options));
}
data = RocketChat.models.Subscriptions.findByUserId(userId, {fields: {rid: 1}}).fetch();
data = data.map(item => item.rid);
const query = {
_id: {
$in: data
}
};
return this.find(query, options);
}
findBySubscriptionUserIdUpdatedAfter(userId, _updatedAt, options) {
if (this.useCache) {
let data = RocketChat.models.Subscriptions.findByUserId(userId).fetch();
data = data.map(function(item) {
if (item._room) {
return item._room;
}
console.log('Empty Room for Subscription', item);
return {};
});
data = data.filter(item => item._updatedAt > _updatedAt);
return this.arrayToCursor(this.processQueryOptionsOnResult(data, options));
}
let ids = RocketChat.models.Subscriptions.findByUserId(userId, {fields: {rid: 1}}).fetch();
ids = ids.map(item => item.rid);
const query = {
_id: {
$in: ids
},
_updatedAt: {
$gt: _updatedAt
}
};
return this.find(query, options);
}
findByNameContaining(name, options) {
const nameRegex = new RegExp(s.trim(s.escapeRegExp(name)), 'i');
const query = {
$or: [
{name: nameRegex},
{
t: 'd',
usernames: nameRegex
}
]
};
return this.find(query, options);
}
findByNameContainingTypesWithUsername(name, types, options) {
const nameRegex = new RegExp(s.trim(s.escapeRegExp(name)), 'i');
const $or = [];
for (const type of Array.from(types)) {
const obj = {name: nameRegex, t: type.type};
if (type.username != null) {
obj.usernames = type.username;
}
if (type.ids != null) {
obj._id = {$in: type.ids};
}
$or.push(obj);
}
const query = {$or};
return this.find(query, options);
}
findContainingTypesWithUsername(types, options) {
const $or = [];
for (const type of Array.from(types)) {
const obj = {t: type.type};
if (type.username != null) {
obj.usernames = type.username;
}
if (type.ids != null) {
obj._id = {$in: type.ids};
}
$or.push(obj);
}
const query = {$or};
return this.find(query, options);
}
findByNameContainingAndTypes(name, types, options) {
const nameRegex = new RegExp(s.trim(s.escapeRegExp(name)), 'i');
const query = {
t: {
$in: types
},
$or: [
{name: nameRegex},
{
t: 'd',
usernames: nameRegex
}
]
};
return this.find(query, options);
}
findByNameAndTypeNotDefault(name, type, options) {
const query = {
t: type,
name,
default: {
$ne: true
}
};
// do not use cache
return this._db.find(query, options);
}
findByNameAndTypeNotContainingUsername(name, type, username, options) {
const query = {
t: type,
name,
usernames: {
$ne: username
}
};
// do not use cache
return this._db.find(query, options);
}
findByNameStartingAndTypes(name, types, options) {
const nameRegex = new RegExp(`^${ s.trim(s.escapeRegExp(name)) }`, 'i');
const query = {
t: {
$in: types
},
$or: [
{name: nameRegex},
{
t: 'd',
usernames: nameRegex
}
]
};
return this.find(query, options);
}
findByDefaultAndTypes(defaultValue, types, options) {
const query = {
default: defaultValue,
t: {
$in: types
}
};
return this.find(query, options);
}
findByTypeContainingUsername(type, username, options) {
const query = {
t: type,
usernames: username
};
return this.find(query, options);
}
findByTypeContainingUsernames(type, username, options) {
const query = {
t: type,
usernames: { $all: [].concat(username) }
};
return this.find(query, options);
}
findByTypesAndNotUserIdContainingUsername(types, userId, username, options) {
const query = {
t: {
$in: types
},
uid: {
$ne: userId
},
usernames: username
};
return this.find(query, options);
}
findByContainingUsername(username, options) {
const query = {usernames: username};
return this.find(query, options);
}
findByTypeAndName(type, name, options) {
if (this.useCache) {
return this.cache.findByIndex('t,name', [type, name], options);
}
const query = {
name,
t: type
};
return this.find(query, options);
}
findByTypeAndNameContainingUsername(type, name, username, options) {
const query = {
name,
t: type,
usernames: username
};
return this.find(query, options);
}
findByTypeAndArchivationState(type, archivationstate, options) {
const query = {t: type};
if (archivationstate) {
query.archived = true;
} else {
query.archived = { $ne: true };
}
return this.find(query, options);
}
// UPDATE
addImportIds(_id, importIds) {
importIds = [].concat(importIds);
const query = {_id};
const update = {
$addToSet: {
importIds: {
$each: importIds
}
}
};
return this.update(query, update);
}
archiveById(_id) {
const query = {_id};
const update = {
$set: {
archived: true
}
};
return this.update(query, update);
}
unarchiveById(_id) {
const query = {_id};
const update = {
$set: {
archived: false
}
};
return this.update(query, update);
}
addUsernameById(_id, username, muted) {
const query = {_id};
const update = {
$addToSet: {
usernames: username
}
};
if (muted) {
update.$addToSet.muted = username;
}
return this.update(query, update);
}
addUsernamesById(_id, usernames) {
const query = {_id};
const update = {
$addToSet: {
usernames: {
$each: usernames
}
}
};
return this.update(query, update);
}
addUsernameByName(name, username) {
const query = {name};
const update = {
$addToSet: {
usernames: username
}
};
return this.update(query, update);
}
removeUsernameById(_id, username) {
const query = {_id};
const update = {
$pull: {
usernames: username
}
};
return this.update(query, update);
}
removeUsernamesById(_id, usernames) {
const query = {_id};
const update = {
$pull: {
usernames: {
$in: usernames
}
}
};
return this.update(query, update);
}
removeUsernameFromAll(username) {
const query = {usernames: username};
const update = {
$pull: {
usernames: username
}
};
return this.update(query, update, { multi: true });
}
removeUsernameByName(name, username) {
const query = {name};
const update = {
$pull: {
usernames: username
}
};
return this.update(query, update);
}
setNameById(_id, name, fname) {
const query = {_id};
const update = {
$set: {
name,
fname
}
};
return this.update(query, update);
}
incMsgCountById(_id, inc) {
if (inc == null) { inc = 1; }
const query = {_id};
const update = {
$inc: {
msgs: inc
}
};
return this.update(query, update);
}
incMsgCountAndSetLastMessageTimestampById(_id, inc, lastMessageTimestamp) {
if (inc == null) { inc = 1; }
const query = {_id};
const update = {
$set: {
lm: lastMessageTimestamp
},
$inc: {
msgs: inc
}
};
return this.update(query, update);
}
replaceUsername(previousUsername, username) {
const query = {usernames: previousUsername};
const update = {
$set: {
'usernames.$': username
}
};
return this.update(query, update, { multi: true });
}
replaceMutedUsername(previousUsername, username) {
const query = {muted: previousUsername};
const update = {
$set: {
'muted.$': username
}
};
return this.update(query, update, { multi: true });
}
replaceUsernameOfUserByUserId(userId, username) {
const query = {'u._id': userId};
const update = {
$set: {
'u.username': username
}
};
return this.update(query, update, { multi: true });
}
setJoinCodeById(_id, joinCode) {
let update;
const query = {_id};
if ((joinCode != null ? joinCode.trim() : undefined) !== '') {
update = {
$set: {
joinCodeRequired: true,
joinCode
}
};
} else {
update = {
$set: {
joinCodeRequired: false
},
$unset: {
joinCode: 1
}
};
}
return this.update(query, update);
}
setUserById(_id, user) {
const query = {_id};
const update = {
$set: {
u: {
_id: user._id,
username: user.username
}
}
};
return this.update(query, update);
}
setTypeById(_id, type) {
const query = {_id};
const update = {
$set: {
t: type
}
};
if (type === 'p') {
update.$unset = {default: ''};
}
return this.update(query, update);
}
setTopicById(_id, topic) {
const query = {_id};
const update = {
$set: {
topic
}
};
return this.update(query, update);
}
setAnnouncementById(_id, announcement) {
const query = {_id};
const update = {
$set: {
announcement
}
};
return this.update(query, update);
}
muteUsernameByRoomId(_id, username) {
const query = {_id};
const update = {
$addToSet: {
muted: username
}
};
return this.update(query, update);
}
unmuteUsernameByRoomId(_id, username) {
const query = {_id};
const update = {
$pull: {
muted: username
}
};
return this.update(query, update);
}
saveDefaultById(_id, defaultValue) {
const query = {_id};
const update = {
$set: {
default: defaultValue === 'true'
}
};
return this.update(query, update);
}
setTopicAndTagsById(_id, topic, tags) {
const setData = {};
const unsetData = {};
if (topic != null) {
if (!_.isEmpty(s.trim(topic))) {
setData.topic = s.trim(topic);
} else {
unsetData.topic = 1;
}
}
if (tags != null) {
if (!_.isEmpty(s.trim(tags))) {
setData.tags = s.trim(tags).split(',').map(tag => s.trim(tag));
} else {
unsetData.tags = 1;
}
}
const update = {};
if (!_.isEmpty(setData)) {
update.$set = setData;
}
if (!_.isEmpty(unsetData)) {
update.$unset = unsetData;
}
if (_.isEmpty(update)) {
return;
}
return this.update({ _id }, update);
}
// INSERT
createWithTypeNameUserAndUsernames(type, name, fname, user, usernames, extraData) {
const room = {
name,
fname,
t: type,
usernames,
msgs: 0,
u: {
_id: user._id,
username: user.username
}
};
_.extend(room, extraData);
room._id = this.insert(room);
return room;
}
createWithIdTypeAndName(_id, type, name, extraData) {
const room = {
_id,
ts: new Date(),
t: type,
name,
usernames: [],
msgs: 0
};
_.extend(room, extraData);
this.insert(room);
return room;
}
// REMOVE
removeById(_id) {
const query = {_id};
return this.remove(query);
}
removeByTypeContainingUsername(type, username) {
const query = {
t: type,
usernames: username
};
return this.remove(query);
}
}
RocketChat.models.Rooms = new ModelRooms('room', true);