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-bot-helpers/server/index.js

166 lines
4.4 KiB

/**
* BotHelpers helps bots
* "private" properties use meteor collection cursors, so they stay reactive
* "public" properties use getters to fetch and filter collections as array
*/
class BotHelpers {
constructor() {
this.queries = {
online: { 'status': { $ne: 'offline' } },
users: { 'roles': { $not: { $all: ['bot'] } } }
};
}
// setup collection cursors with array of fields from setting
setupCursors(fieldsSetting) {
this.userFields = {};
if (typeof fieldsSetting === 'string') {
fieldsSetting = fieldsSetting.split(',');
}
fieldsSetting.forEach((n) => {
this.userFields[n.trim()] = 1;
});
this._allUsers = RocketChat.models.Users.find(this.queries.users, { fields: this.userFields });
this._onlineUsers = RocketChat.models.Users.find({ $and: [this.queries.users, this.queries.online] }, { fields: this.userFields });
}
// request methods or props as arguments to Meteor.call
request(prop, ...params) {
if (typeof this[prop] === 'undefined') {
return null;
} else if (typeof this[prop] === 'function') {
return this[prop](...params);
} else {
return this[prop];
}
}
addUserToRole(userName, roleName) {
Meteor.call('authorization:addUserToRole', roleName, userName);
}
removeUserFromRole(userName, roleName) {
Meteor.call('authorization:removeUserFromRole', roleName, userName);
}
addUserToRoom(userName, room) {
const foundRoom = RocketChat.models.Rooms.findOneByIdOrName(room);
if (!_.isObject(foundRoom)) {
throw new Meteor.Error('invalid-channel');
}
const data = {};
data.rid = foundRoom._id;
data.username = userName;
Meteor.call('addUserToRoom', data);
}
removeUserFromRoom(userName, room) {
const foundRoom = RocketChat.models.Rooms.findOneByIdOrName(room);
if (!_.isObject(foundRoom)) {
throw new Meteor.Error('invalid-channel');
}
const data = {};
data.rid = foundRoom._id;
data.username = userName;
Meteor.call('removeUserFromRoom', data);
}
// generic error whenever property access insufficient to fill request
requestError() {
throw new Meteor.Error('error-not-allowed', 'Bot request not allowed', { method: 'botRequest', action: 'bot_request' });
}
// "public" properties accessed by getters
// allUsers / onlineUsers return whichever properties are enabled by settings
get allUsers() {
9 years ago
if (!Object.keys(this.userFields).length) {
this.requestError();
return false;
} else {
return this._allUsers.fetch();
}
}
get onlineUsers() {
9 years ago
if (!Object.keys(this.userFields).length) {
this.requestError();
return false;
} else {
return this._onlineUsers.fetch();
}
}
get allUsernames() {
if (!this.userFields.hasOwnProperty('username')) {
this.requestError();
return false;
} else {
return this._allUsers.fetch().map((user) => user.username);
}
}
get onlineUsernames() {
if (!this.userFields.hasOwnProperty('username')) {
this.requestError();
return false;
} else {
return this._onlineUsers.fetch().map((user) => user.username);
}
}
get allNames() {
if (!this.userFields.hasOwnProperty('name')) {
this.requestError();
return false;
} else {
return this._allUsers.fetch().map((user) => user.name);
}
}
get onlineNames() {
if (!this.userFields.hasOwnProperty('name')) {
this.requestError();
return false;
} else {
return this._onlineUsers.fetch().map((user) => user.name);
}
}
get allIDs() {
if (!this.userFields.hasOwnProperty('_id') || !this.userFields.hasOwnProperty('username')) {
this.requestError();
return false;
} else {
return this._allUsers.fetch().map((user) => {
return { 'id': user._id, 'name': user.username };
});
}
}
get onlineIDs() {
if (!this.userFields.hasOwnProperty('_id') || !this.userFields.hasOwnProperty('username')) {
this.requestError();
return false;
} else {
return this._onlineUsers.fetch().map((user) => {
return { 'id': user._id, 'name': user.username };
});
}
}
}
// add class to meteor methods
const botHelpers = new BotHelpers();
// init cursors with fields setting and update on setting change
RocketChat.settings.get('BotHelpers_userFields', function(settingKey, settingValue) {
botHelpers.setupCursors(settingValue);
});
Meteor.methods({
botRequest: (...args) => {
const userID = Meteor.userId();
if (userID && RocketChat.authz.hasRole(userID, 'bot')) {
return botHelpers.request(...args);
} else {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'botRequest' });
}
}
});