diff --git a/packages/rocketchat-api/package.js b/packages/rocketchat-api/package.js index 969cca9a542c..a6664d10b8f1 100644 --- a/packages/rocketchat-api/package.js +++ b/packages/rocketchat-api/package.js @@ -13,6 +13,7 @@ Package.onUse(function(api) { 'rocketchat:lib', 'rocketchat:models', 'rocketchat:settings', + 'rocketchat:assets', 'rocketchat:utils', 'rocketchat:metrics', 'rocketchat:authorization', diff --git a/packages/rocketchat-api/server/v1/assets.js b/packages/rocketchat-api/server/v1/assets.js index 774ee3c8d58f..c69b619b27fe 100644 --- a/packages/rocketchat-api/server/v1/assets.js +++ b/packages/rocketchat-api/server/v1/assets.js @@ -1,8 +1,9 @@ import { Meteor } from 'meteor/meteor'; +import { RocketChatAssets } from 'meteor/rocketchat:assets'; import Busboy from 'busboy'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { API } from '../api'; -RocketChat.API.v1.addRoute('assets.setAsset', { authRequired: true }, { +API.v1.addRoute('assets.setAsset', { authRequired: true }, { post() { const busboy = new Busboy({ headers: this.request.headers }); const fields = {}; @@ -11,7 +12,7 @@ RocketChat.API.v1.addRoute('assets.setAsset', { authRequired: true }, { Meteor.wrapAsync((callback) => { busboy.on('field', (fieldname, value) => fields[fieldname] = value); busboy.on('file', Meteor.bindEnvironment((fieldname, file, filename, encoding, mimetype) => { - const isValidAsset = Object.keys(RocketChat.Assets.assets).includes(fieldname); + const isValidAsset = Object.keys(RocketChatAssets.assets).includes(fieldname); if (!isValidAsset) { callback(new Meteor.Error('error-invalid-asset', 'Invalid asset')); } @@ -35,14 +36,14 @@ RocketChat.API.v1.addRoute('assets.setAsset', { authRequired: true }, { if (fields.refreshAllClients) { Meteor.runAsUser(this.userId, () => Meteor.call('refreshClients')); } - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('assets.unsetAsset', { authRequired: true }, { +API.v1.addRoute('assets.unsetAsset', { authRequired: true }, { post() { const { assetName, refreshAllClients } = this.bodyParams; - const isValidAsset = Object.keys(RocketChat.Assets.assets).includes(assetName); + const isValidAsset = Object.keys(RocketChatAssets.assets).includes(assetName); if (!isValidAsset) { throw new Meteor.Error('error-invalid-asset', 'Invalid asset'); } @@ -50,6 +51,6 @@ RocketChat.API.v1.addRoute('assets.unsetAsset', { authRequired: true }, { if (refreshAllClients) { Meteor.runAsUser(this.userId, () => Meteor.call('refreshClients')); } - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); diff --git a/packages/rocketchat-api/server/v1/channels.js b/packages/rocketchat-api/server/v1/channels.js index 6332e0ef840e..4fc61f4c6780 100644 --- a/packages/rocketchat-api/server/v1/channels.js +++ b/packages/rocketchat-api/server/v1/channels.js @@ -1,5 +1,8 @@ import { Meteor } from 'meteor/meteor'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { Rooms, Subscriptions, Messages, Uploads, Integrations, Users } from 'meteor/rocketchat:models'; +import { hasPermission } from 'meteor/rocketchat:authorization'; +import { composeMessageObjectWithUser } from 'meteor/rocketchat:utils'; +import { API } from '../api'; import _ from 'underscore'; // Returns the channel IF found otherwise it will return the failure of why it didn't. Check the `statusCode` property @@ -8,13 +11,13 @@ function findChannelByIdOrName({ params, checkedArchived = true, userId }) { throw new Meteor.Error('error-roomid-param-not-provided', 'The parameter "roomId" or "roomName" is required'); } - const fields = { ...RocketChat.API.v1.defaultFieldsToExclude }; + const fields = { ...API.v1.defaultFieldsToExclude }; let room; if (params.roomId) { - room = RocketChat.models.Rooms.findOneById(params.roomId, { fields }); + room = Rooms.findOneById(params.roomId, { fields }); } else if (params.roomName) { - room = RocketChat.models.Rooms.findOneByName(params.roomName, { fields }); + room = Rooms.findOneByName(params.roomName, { fields }); } if (!room || room.t !== 'c') { @@ -25,13 +28,13 @@ function findChannelByIdOrName({ params, checkedArchived = true, userId }) { throw new Meteor.Error('error-room-archived', `The channel, ${ room.name }, is archived`); } if (userId && room.lastMessage) { - room.lastMessage = RocketChat.composeMessageObjectWithUser(room.lastMessage, userId); + room.lastMessage = composeMessageObjectWithUser(room.lastMessage, userId); } return room; } -RocketChat.API.v1.addRoute('channels.addAll', { authRequired: true }, { +API.v1.addRoute('channels.addAll', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -39,13 +42,13 @@ RocketChat.API.v1.addRoute('channels.addAll', { authRequired: true }, { Meteor.call('addAllUserToRoom', findResult._id, this.bodyParams.activeUsersOnly); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.addModerator', { authRequired: true }, { +API.v1.addRoute('channels.addModerator', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -55,11 +58,11 @@ RocketChat.API.v1.addRoute('channels.addModerator', { authRequired: true }, { Meteor.call('addRoomModerator', findResult._id, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.addOwner', { authRequired: true }, { +API.v1.addRoute('channels.addOwner', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -69,11 +72,11 @@ RocketChat.API.v1.addRoute('channels.addOwner', { authRequired: true }, { Meteor.call('addRoomOwner', findResult._id, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.archive', { authRequired: true }, { +API.v1.addRoute('channels.archive', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -81,35 +84,35 @@ RocketChat.API.v1.addRoute('channels.archive', { authRequired: true }, { Meteor.call('archiveRoom', findResult._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.close', { authRequired: true }, { +API.v1.addRoute('channels.close', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); - const sub = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId); + const sub = Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId); if (!sub) { - return RocketChat.API.v1.failure(`The user/callee is not in the channel "${ findResult.name }.`); + return API.v1.failure(`The user/callee is not in the channel "${ findResult.name }.`); } if (!sub.open) { - return RocketChat.API.v1.failure(`The channel, ${ findResult.name }, is already closed to the sender`); + return API.v1.failure(`The channel, ${ findResult.name }, is already closed to the sender`); } Meteor.runAsUser(this.userId, () => { Meteor.call('hideRoom', findResult._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.counters', { authRequired: true }, { +API.v1.addRoute('channels.counters', { authRequired: true }, { get() { - const access = RocketChat.authz.hasPermission(this.userId, 'view-room-administration'); + const access = hasPermission(this.userId, 'view-room-administration'); const { userId } = this.requestParams(); let user = this.userId; let unreads = null; @@ -122,7 +125,7 @@ RocketChat.API.v1.addRoute('channels.counters', { authRequired: true }, { if (userId) { if (!access) { - return RocketChat.API.v1.unauthorized(); + return API.v1.unauthorized(); } user = userId; } @@ -130,11 +133,11 @@ RocketChat.API.v1.addRoute('channels.counters', { authRequired: true }, { params: this.requestParams(), returnUsernames: true, }); - const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user); + const subscription = Subscriptions.findOneByRoomIdAndUserId(room._id, user); const lm = room.lm ? room.lm : room._updatedAt; if (typeof subscription !== 'undefined' && subscription.open) { - unreads = RocketChat.models.Messages.countVisibleByRoomIdBetweenTimestampsInclusive(subscription.rid, subscription.ls, lm); + unreads = Messages.countVisibleByRoomIdBetweenTimestampsInclusive(subscription.rid, subscription.ls, lm); unreadsFrom = subscription.ls || subscription.ts; userMentions = subscription.userMentions; joined = true; @@ -146,7 +149,7 @@ RocketChat.API.v1.addRoute('channels.counters', { authRequired: true }, { members = room.usersCount; } - return RocketChat.API.v1.success({ + return API.v1.success({ joined, members, unreads, @@ -161,7 +164,7 @@ RocketChat.API.v1.addRoute('channels.counters', { authRequired: true }, { // Channel -> create function createChannelValidator(params) { - if (!RocketChat.authz.hasPermission(params.user.value, 'create-c')) { + if (!hasPermission(params.user.value, 'create-c')) { throw new Error('unauthorized'); } @@ -187,20 +190,20 @@ function createChannel(userId, params) { }; } -RocketChat.API.channels = {}; -RocketChat.API.channels.create = { +API.channels = {}; +API.channels.create = { validate: createChannelValidator, execute: createChannel, }; -RocketChat.API.v1.addRoute('channels.create', { authRequired: true }, { +API.v1.addRoute('channels.create', { authRequired: true }, { post() { const { userId, bodyParams } = this; let error; try { - RocketChat.API.channels.create.validate({ + API.channels.create.validate({ user: { value: userId, }, @@ -215,9 +218,9 @@ RocketChat.API.v1.addRoute('channels.create', { authRequired: true }, { }); } catch (e) { if (e.message === 'unauthorized') { - error = RocketChat.API.v1.unauthorized(); + error = API.v1.unauthorized(); } else { - error = RocketChat.API.v1.failure(e.message); + error = API.v1.failure(e.message); } } @@ -225,11 +228,11 @@ RocketChat.API.v1.addRoute('channels.create', { authRequired: true }, { return error; } - return RocketChat.API.v1.success(RocketChat.API.channels.create.execute(userId, bodyParams)); + return API.v1.success(API.channels.create.execute(userId, bodyParams)); }, }); -RocketChat.API.v1.addRoute('channels.delete', { authRequired: true }, { +API.v1.addRoute('channels.delete', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); @@ -237,11 +240,11 @@ RocketChat.API.v1.addRoute('channels.delete', { authRequired: true }, { Meteor.call('eraseRoom', findResult._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.files', { authRequired: true }, { +API.v1.addRoute('channels.files', { authRequired: true }, { get() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); const addUserObjectToEveryObject = (file) => { @@ -260,27 +263,27 @@ RocketChat.API.v1.addRoute('channels.files', { authRequired: true }, { const ourQuery = Object.assign({}, query, { rid: findResult._id }); - const files = RocketChat.models.Uploads.find(ourQuery, { + const files = Uploads.find(ourQuery, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ files: files.map(addUserObjectToEveryObject), count: files.length, offset, - total: RocketChat.models.Uploads.find(ourQuery).count(), + total: Uploads.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute('channels.getIntegrations', { authRequired: true }, { +API.v1.addRoute('channels.getIntegrations', { authRequired: true }, { get() { - if (!RocketChat.authz.hasPermission(this.userId, 'manage-integrations')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'manage-integrations')) { + return API.v1.unauthorized(); } const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); @@ -305,23 +308,23 @@ RocketChat.API.v1.addRoute('channels.getIntegrations', { authRequired: true }, { ourQuery = Object.assign({}, query, ourQuery); - const integrations = RocketChat.models.Integrations.find(ourQuery, { + const integrations = Integrations.find(ourQuery, { sort: sort ? sort : { _createdAt: 1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ integrations, count: integrations.length, offset, - total: RocketChat.models.Integrations.find(ourQuery).count(), + total: Integrations.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute('channels.history', { authRequired: true }, { +API.v1.addRoute('channels.history', { authRequired: true }, { get() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); @@ -357,16 +360,16 @@ RocketChat.API.v1.addRoute('channels.history', { authRequired: true }, { }); if (!result) { - return RocketChat.API.v1.unauthorized(); + return API.v1.unauthorized(); } - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); -RocketChat.API.v1.addRoute('channels.info', { authRequired: true }, { +API.v1.addRoute('channels.info', { authRequired: true }, { get() { - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false, @@ -376,7 +379,7 @@ RocketChat.API.v1.addRoute('channels.info', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('channels.invite', { authRequired: true }, { +API.v1.addRoute('channels.invite', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -386,13 +389,13 @@ RocketChat.API.v1.addRoute('channels.invite', { authRequired: true }, { Meteor.call('addUserToRoom', { rid: findResult._id, username: user.username }); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.join', { authRequired: true }, { +API.v1.addRoute('channels.join', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -400,13 +403,13 @@ RocketChat.API.v1.addRoute('channels.join', { authRequired: true }, { Meteor.call('joinRoom', findResult._id, this.bodyParams.joinCode); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.kick', { authRequired: true }, { +API.v1.addRoute('channels.kick', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -416,13 +419,13 @@ RocketChat.API.v1.addRoute('channels.kick', { authRequired: true }, { Meteor.call('removeUserFromRoom', { rid: findResult._id, username: user.username }); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.leave', { authRequired: true }, { +API.v1.addRoute('channels.leave', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -430,31 +433,31 @@ RocketChat.API.v1.addRoute('channels.leave', { authRequired: true }, { Meteor.call('leaveRoom', findResult._id); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.list', { authRequired: true }, { +API.v1.addRoute('channels.list', { authRequired: true }, { get: { // This is defined as such only to provide an example of how the routes can be defined :X action() { const { offset, count } = this.getPaginationItems(); const { sort, fields, query } = this.parseJsonQuery(); - const hasPermissionToSeeAllPublicChannels = RocketChat.authz.hasPermission(this.userId, 'view-c-room'); + const hasPermissionToSeeAllPublicChannels = hasPermission(this.userId, 'view-c-room'); const ourQuery = { ...query, t: 'c' }; if (!hasPermissionToSeeAllPublicChannels) { - if (!RocketChat.authz.hasPermission(this.userId, 'view-joined-room')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'view-joined-room')) { + return API.v1.unauthorized(); } - const roomIds = RocketChat.models.Subscriptions.findByUserIdAndType(this.userId, 'c', { fields: { rid: 1 } }).fetch().map((s) => s.rid); + const roomIds = Subscriptions.findByUserIdAndType(this.userId, 'c', { fields: { rid: 1 } }).fetch().map((s) => s.rid); ourQuery._id = { $in: roomIds }; } - const cursor = RocketChat.models.Rooms.find(ourQuery, { + const cursor = Rooms.find(ourQuery, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, @@ -465,7 +468,7 @@ RocketChat.API.v1.addRoute('channels.list', { authRequired: true }, { const rooms = cursor.fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ channels: rooms.map((room) => this.composeRoomWithLastMessage(room, this.userId)), count: rooms.length, offset, @@ -475,13 +478,13 @@ RocketChat.API.v1.addRoute('channels.list', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('channels.list.joined', { authRequired: true }, { +API.v1.addRoute('channels.list.joined', { authRequired: true }, { get() { const { offset, count } = this.getPaginationItems(); const { sort, fields } = this.parseJsonQuery(); // TODO: CACHE: Add Breacking notice since we removed the query param - const cursor = RocketChat.models.Rooms.findBySubscriptionTypeAndUserId('c', this.userId, { + const cursor = Rooms.findBySubscriptionTypeAndUserId('c', this.userId, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, @@ -491,7 +494,7 @@ RocketChat.API.v1.addRoute('channels.list.joined', { authRequired: true }, { const totalCount = cursor.count(); const rooms = cursor.fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ channels: rooms.map((room) => this.composeRoomWithLastMessage(room, this.userId)), offset, count: rooms.length, @@ -500,21 +503,21 @@ RocketChat.API.v1.addRoute('channels.list.joined', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('channels.members', { authRequired: true }, { +API.v1.addRoute('channels.members', { authRequired: true }, { get() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false, }); - if (findResult.broadcast && !RocketChat.authz.hasPermission(this.userId, 'view-broadcast-member-list')) { - return RocketChat.API.v1.unauthorized(); + if (findResult.broadcast && !hasPermission(this.userId, 'view-broadcast-member-list')) { + return API.v1.unauthorized(); } const { offset, count } = this.getPaginationItems(); const { sort = {} } = this.parseJsonQuery(); - const subscriptions = RocketChat.models.Subscriptions.findByRoomId(findResult._id, { + const subscriptions = Subscriptions.findByRoomId(findResult._id, { fields: { 'u._id': 1 }, sort: { 'u.username': sort.username != null ? sort.username : 1 }, skip: offset, @@ -525,12 +528,12 @@ RocketChat.API.v1.addRoute('channels.members', { authRequired: true }, { const members = subscriptions.fetch().map((s) => s.u && s.u._id); - const users = RocketChat.models.Users.find({ _id: { $in: members } }, { + const users = Users.find({ _id: { $in: members } }, { fields: { _id: 1, username: 1, name: 1, status: 1, utcOffset: 1 }, sort: { username: sort.username != null ? sort.username : 1 }, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ members: users, count: users.length, offset, @@ -539,7 +542,7 @@ RocketChat.API.v1.addRoute('channels.members', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('channels.messages', { authRequired: true }, { +API.v1.addRoute('channels.messages', { authRequired: true }, { get() { const findResult = findChannelByIdOrName({ params: this.requestParams(), @@ -551,14 +554,14 @@ RocketChat.API.v1.addRoute('channels.messages', { authRequired: true }, { const ourQuery = Object.assign({}, query, { rid: findResult._id }); // Special check for the permissions - if (RocketChat.authz.hasPermission(this.userId, 'view-joined-room') && !RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId, { fields: { _id: 1 } })) { - return RocketChat.API.v1.unauthorized(); + if (hasPermission(this.userId, 'view-joined-room') && !Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId, { fields: { _id: 1 } })) { + return API.v1.unauthorized(); } - if (!RocketChat.authz.hasPermission(this.userId, 'view-c-room')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'view-c-room')) { + return API.v1.unauthorized(); } - const cursor = RocketChat.models.Messages.find(ourQuery, { + const cursor = Messages.find(ourQuery, { sort: sort ? sort : { ts: -1 }, skip: offset, limit: count, @@ -568,8 +571,8 @@ RocketChat.API.v1.addRoute('channels.messages', { authRequired: true }, { const total = cursor.count(); const messages = cursor.fetch(); - return RocketChat.API.v1.success({ - messages: messages.map((record) => RocketChat.composeMessageObjectWithUser(record, this.userId)), + return API.v1.success({ + messages: messages.map((record) => composeMessageObjectWithUser(record, this.userId)), count: messages.length, offset, total, @@ -605,24 +608,24 @@ RocketChat.API.v1.addRoute('channels.messages', { authRequired: true }, { // } // }); -RocketChat.API.v1.addRoute('channels.online', { authRequired: true }, { +API.v1.addRoute('channels.online', { authRequired: true }, { get() { const { query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query, { t: 'c' }); - const room = RocketChat.models.Rooms.findOne(ourQuery); + const room = Rooms.findOne(ourQuery); if (room == null) { - return RocketChat.API.v1.failure('Channel does not exists'); + return API.v1.failure('Channel does not exists'); } - const online = RocketChat.models.Users.findUsersNotOffline({ + const online = Users.findUsersNotOffline({ fields: { username: 1 }, }).fetch(); const onlineInRoom = []; online.forEach((user) => { - const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, { fields: { _id: 1 } }); + const subscription = Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, { fields: { _id: 1 } }); if (subscription) { onlineInRoom.push({ _id: user._id, @@ -631,35 +634,35 @@ RocketChat.API.v1.addRoute('channels.online', { authRequired: true }, { } }); - return RocketChat.API.v1.success({ + return API.v1.success({ online: onlineInRoom, }); }, }); -RocketChat.API.v1.addRoute('channels.open', { authRequired: true }, { +API.v1.addRoute('channels.open', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); - const sub = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId); + const sub = Subscriptions.findOneByRoomIdAndUserId(findResult._id, this.userId); if (!sub) { - return RocketChat.API.v1.failure(`The user/callee is not in the channel "${ findResult.name }".`); + return API.v1.failure(`The user/callee is not in the channel "${ findResult.name }".`); } if (sub.open) { - return RocketChat.API.v1.failure(`The channel, ${ findResult.name }, is already open to the sender`); + return API.v1.failure(`The channel, ${ findResult.name }, is already open to the sender`); } Meteor.runAsUser(this.userId, () => { Meteor.call('openRoom', findResult._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.removeModerator', { authRequired: true }, { +API.v1.addRoute('channels.removeModerator', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -669,11 +672,11 @@ RocketChat.API.v1.addRoute('channels.removeModerator', { authRequired: true }, { Meteor.call('removeRoomModerator', findResult._id, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.removeOwner', { authRequired: true }, { +API.v1.addRoute('channels.removeOwner', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -683,36 +686,36 @@ RocketChat.API.v1.addRoute('channels.removeOwner', { authRequired: true }, { Meteor.call('removeRoomOwner', findResult._id, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.rename', { authRequired: true }, { +API.v1.addRoute('channels.rename', { authRequired: true }, { post() { if (!this.bodyParams.name || !this.bodyParams.name.trim()) { - return RocketChat.API.v1.failure('The bodyParam "name" is required'); + return API.v1.failure('The bodyParam "name" is required'); } const findResult = findChannelByIdOrName({ params: { roomId: this.bodyParams.roomId } }); if (findResult.name === this.bodyParams.name) { - return RocketChat.API.v1.failure('The channel name is the same as what it would be renamed to.'); + return API.v1.failure('The channel name is the same as what it would be renamed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'roomName', this.bodyParams.name); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: { roomId: this.bodyParams.roomId }, userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.setCustomFields', { authRequired: true }, { +API.v1.addRoute('channels.setCustomFields', { authRequired: true }, { post() { if (!this.bodyParams.customFields || !(typeof this.bodyParams.customFields === 'object')) { - return RocketChat.API.v1.failure('The bodyParam "customFields" is required with a type like object.'); + return API.v1.failure('The bodyParam "customFields" is required with a type like object.'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -721,60 +724,60 @@ RocketChat.API.v1.addRoute('channels.setCustomFields', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult._id, 'roomCustomFields', this.bodyParams.customFields); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.setDefault', { authRequired: true }, { +API.v1.addRoute('channels.setDefault', { authRequired: true }, { post() { if (typeof this.bodyParams.default === 'undefined') { - return RocketChat.API.v1.failure('The bodyParam "default" is required', 'error-channels-setdefault-is-same'); + return API.v1.failure('The bodyParam "default" is required', 'error-channels-setdefault-is-same'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); if (findResult.default === this.bodyParams.default) { - return RocketChat.API.v1.failure('The channel default setting is the same as what it would be changed to.', 'error-channels-setdefault-missing-default-param'); + return API.v1.failure('The channel default setting is the same as what it would be changed to.', 'error-channels-setdefault-missing-default-param'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'default', this.bodyParams.default.toString()); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.setDescription', { authRequired: true }, { +API.v1.addRoute('channels.setDescription', { authRequired: true }, { post() { if (!this.bodyParams.description || !this.bodyParams.description.trim()) { - return RocketChat.API.v1.failure('The bodyParam "description" is required'); + return API.v1.failure('The bodyParam "description" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); if (findResult.description === this.bodyParams.description) { - return RocketChat.API.v1.failure('The channel description is the same as what it would be changed to.'); + return API.v1.failure('The channel description is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'roomDescription', this.bodyParams.description); }); - return RocketChat.API.v1.success({ + return API.v1.success({ description: this.bodyParams.description, }); }, }); -RocketChat.API.v1.addRoute('channels.setJoinCode', { authRequired: true }, { +API.v1.addRoute('channels.setJoinCode', { authRequired: true }, { post() { if (!this.bodyParams.joinCode || !this.bodyParams.joinCode.trim()) { - return RocketChat.API.v1.failure('The bodyParam "joinCode" is required'); + return API.v1.failure('The bodyParam "joinCode" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -783,82 +786,82 @@ RocketChat.API.v1.addRoute('channels.setJoinCode', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult._id, 'joinCode', this.bodyParams.joinCode); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.setPurpose', { authRequired: true }, { +API.v1.addRoute('channels.setPurpose', { authRequired: true }, { post() { if (!this.bodyParams.purpose || !this.bodyParams.purpose.trim()) { - return RocketChat.API.v1.failure('The bodyParam "purpose" is required'); + return API.v1.failure('The bodyParam "purpose" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); if (findResult.description === this.bodyParams.purpose) { - return RocketChat.API.v1.failure('The channel purpose (description) is the same as what it would be changed to.'); + return API.v1.failure('The channel purpose (description) is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'roomDescription', this.bodyParams.purpose); }); - return RocketChat.API.v1.success({ + return API.v1.success({ purpose: this.bodyParams.purpose, }); }, }); -RocketChat.API.v1.addRoute('channels.setReadOnly', { authRequired: true }, { +API.v1.addRoute('channels.setReadOnly', { authRequired: true }, { post() { if (typeof this.bodyParams.readOnly === 'undefined') { - return RocketChat.API.v1.failure('The bodyParam "readOnly" is required'); + return API.v1.failure('The bodyParam "readOnly" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); if (findResult.ro === this.bodyParams.readOnly) { - return RocketChat.API.v1.failure('The channel read only setting is the same as what it would be changed to.'); + return API.v1.failure('The channel read only setting is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'readOnly', this.bodyParams.readOnly); }); - return RocketChat.API.v1.success({ + return API.v1.success({ channel: findChannelByIdOrName({ params: this.requestParams(), userId: this.userId }), }); }, }); -RocketChat.API.v1.addRoute('channels.setTopic', { authRequired: true }, { +API.v1.addRoute('channels.setTopic', { authRequired: true }, { post() { if (!this.bodyParams.topic || !this.bodyParams.topic.trim()) { - return RocketChat.API.v1.failure('The bodyParam "topic" is required'); + return API.v1.failure('The bodyParam "topic" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); if (findResult.topic === this.bodyParams.topic) { - return RocketChat.API.v1.failure('The channel topic is the same as what it would be changed to.'); + return API.v1.failure('The channel topic is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'roomTopic', this.bodyParams.topic); }); - return RocketChat.API.v1.success({ + return API.v1.success({ topic: this.bodyParams.topic, }); }, }); -RocketChat.API.v1.addRoute('channels.setAnnouncement', { authRequired: true }, { +API.v1.addRoute('channels.setAnnouncement', { authRequired: true }, { post() { if (!this.bodyParams.announcement || !this.bodyParams.announcement.trim()) { - return RocketChat.API.v1.failure('The bodyParam "announcement" is required'); + return API.v1.failure('The bodyParam "announcement" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); @@ -867,58 +870,58 @@ RocketChat.API.v1.addRoute('channels.setAnnouncement', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult._id, 'roomAnnouncement', this.bodyParams.announcement); }); - return RocketChat.API.v1.success({ + return API.v1.success({ announcement: this.bodyParams.announcement, }); }, }); -RocketChat.API.v1.addRoute('channels.setType', { authRequired: true }, { +API.v1.addRoute('channels.setType', { authRequired: true }, { post() { if (!this.bodyParams.type || !this.bodyParams.type.trim()) { - return RocketChat.API.v1.failure('The bodyParam "type" is required'); + return API.v1.failure('The bodyParam "type" is required'); } const findResult = findChannelByIdOrName({ params: this.requestParams() }); if (findResult.t === this.bodyParams.type) { - return RocketChat.API.v1.failure('The channel type is the same as what it would be changed to.'); + return API.v1.failure('The channel type is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult._id, 'roomType', this.bodyParams.type); }); - return RocketChat.API.v1.success({ - channel: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult._id, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + channel: this.composeRoomWithLastMessage(Rooms.findOneById(findResult._id, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('channels.unarchive', { authRequired: true }, { +API.v1.addRoute('channels.unarchive', { authRequired: true }, { post() { const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false }); if (!findResult.archived) { - return RocketChat.API.v1.failure(`The channel, ${ findResult.name }, is not archived`); + return API.v1.failure(`The channel, ${ findResult.name }, is not archived`); } Meteor.runAsUser(this.userId, () => { Meteor.call('unarchiveRoom', findResult._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('channels.getAllUserMentionsByChannel', { authRequired: true }, { +API.v1.addRoute('channels.getAllUserMentionsByChannel', { authRequired: true }, { get() { const { roomId } = this.requestParams(); const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); if (!roomId) { - return RocketChat.API.v1.failure('The request param "roomId" is required'); + return API.v1.failure('The request param "roomId" is required'); } const mentions = Meteor.runAsUser(this.userId, () => Meteor.call('getUserMentionsByChannel', { @@ -935,7 +938,7 @@ RocketChat.API.v1.addRoute('channels.getAllUserMentionsByChannel', { authRequire options: {}, })); - return RocketChat.API.v1.success({ + return API.v1.success({ mentions, count: mentions.length, offset, @@ -944,25 +947,25 @@ RocketChat.API.v1.addRoute('channels.getAllUserMentionsByChannel', { authRequire }, }); -RocketChat.API.v1.addRoute('channels.roles', { authRequired: true }, { +API.v1.addRoute('channels.roles', { authRequired: true }, { get() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); const roles = Meteor.runAsUser(this.userId, () => Meteor.call('getRoomRoles', findResult._id)); - return RocketChat.API.v1.success({ + return API.v1.success({ roles, }); }, }); -RocketChat.API.v1.addRoute('channels.moderators', { authRequired: true }, { +API.v1.addRoute('channels.moderators', { authRequired: true }, { get() { const findResult = findChannelByIdOrName({ params: this.requestParams() }); - const moderators = RocketChat.models.Subscriptions.findByRoomIdAndRoles(findResult._id, ['moderator'], { fields: { u: 1 } }).fetch().map((sub) => sub.u); + const moderators = Subscriptions.findByRoomIdAndRoles(findResult._id, ['moderator'], { fields: { u: 1 } }).fetch().map((sub) => sub.u); - return RocketChat.API.v1.success({ + return API.v1.success({ moderators, }); }, diff --git a/packages/rocketchat-api/server/v1/chat.js b/packages/rocketchat-api/server/v1/chat.js index f6f92ae02444..f83b8dc2c804 100644 --- a/packages/rocketchat-api/server/v1/chat.js +++ b/packages/rocketchat-api/server/v1/chat.js @@ -1,9 +1,12 @@ import { Meteor } from 'meteor/meteor'; -import { RocketChat } from 'meteor/rocketchat:lib'; import { Match, check } from 'meteor/check'; import { processWebhookMessage } from 'meteor/rocketchat:integrations'; +import { Messages } from 'meteor/rocketchat:models'; +import { hasPermission } from 'meteor/rocketchat:authorization'; +import { composeMessageObjectWithUser } from 'meteor/rocketchat:utils'; +import { API } from '../api'; -RocketChat.API.v1.addRoute('chat.delete', { authRequired: true }, { +API.v1.addRoute('chat.delete', { authRequired: true }, { post() { check(this.bodyParams, Match.ObjectIncluding({ msgId: String, @@ -11,25 +14,25 @@ RocketChat.API.v1.addRoute('chat.delete', { authRequired: true }, { asUser: Match.Maybe(Boolean), })); - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.msgId, { fields: { u: 1, rid: 1 } }); + const msg = Messages.findOneById(this.bodyParams.msgId, { fields: { u: 1, rid: 1 } }); if (!msg) { - return RocketChat.API.v1.failure(`No message found with the id of "${ this.bodyParams.msgId }".`); + return API.v1.failure(`No message found with the id of "${ this.bodyParams.msgId }".`); } if (this.bodyParams.roomId !== msg.rid) { - return RocketChat.API.v1.failure('The room id provided does not match where the message is from.'); + return API.v1.failure('The room id provided does not match where the message is from.'); } - if (this.bodyParams.asUser && msg.u._id !== this.userId && !RocketChat.authz.hasPermission(this.userId, 'force-delete-message', msg.rid)) { - return RocketChat.API.v1.failure('Unauthorized. You must have the permission "force-delete-message" to delete other\'s message as them.'); + if (this.bodyParams.asUser && msg.u._id !== this.userId && !hasPermission(this.userId, 'force-delete-message', msg.rid)) { + return API.v1.failure('Unauthorized. You must have the permission "force-delete-message" to delete other\'s message as them.'); } Meteor.runAsUser(this.bodyParams.asUser ? msg.u._id : this.userId, () => { Meteor.call('deleteMessage', { _id: msg._id }); }); - return RocketChat.API.v1.success({ + return API.v1.success({ _id: msg._id, ts: Date.now(), message: msg, @@ -37,7 +40,7 @@ RocketChat.API.v1.addRoute('chat.delete', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('chat.syncMessages', { authRequired: true }, { +API.v1.addRoute('chat.syncMessages', { authRequired: true }, { get() { const { roomId, lastUpdate } = this.queryParams; @@ -57,22 +60,22 @@ RocketChat.API.v1.addRoute('chat.syncMessages', { authRequired: true }, { }); if (!result) { - return RocketChat.API.v1.failure(); + return API.v1.failure(); } - return RocketChat.API.v1.success({ + return API.v1.success({ result: { - updated: result.updated.map((message) => RocketChat.composeMessageObjectWithUser(message, this.userId)), - deleted: result.deleted.map((message) => RocketChat.composeMessageObjectWithUser(message, this.userId)), + updated: result.updated.map((message) => composeMessageObjectWithUser(message, this.userId)), + deleted: result.deleted.map((message) => composeMessageObjectWithUser(message, this.userId)), }, }); }, }); -RocketChat.API.v1.addRoute('chat.getMessage', { authRequired: true }, { +API.v1.addRoute('chat.getMessage', { authRequired: true }, { get() { if (!this.queryParams.msgId) { - return RocketChat.API.v1.failure('The "msgId" query parameter must be provided.'); + return API.v1.failure('The "msgId" query parameter must be provided.'); } let msg; @@ -81,22 +84,22 @@ RocketChat.API.v1.addRoute('chat.getMessage', { authRequired: true }, { }); if (!msg) { - return RocketChat.API.v1.failure(); + return API.v1.failure(); } - return RocketChat.API.v1.success({ - message: RocketChat.composeMessageObjectWithUser(msg, this.userId), + return API.v1.success({ + message: composeMessageObjectWithUser(msg, this.userId), }); }, }); -RocketChat.API.v1.addRoute('chat.pinMessage', { authRequired: true }, { +API.v1.addRoute('chat.pinMessage', { authRequired: true }, { post() { if (!this.bodyParams.messageId || !this.bodyParams.messageId.trim()) { throw new Meteor.Error('error-messageid-param-not-provided', 'The required "messageId" param is missing.'); } - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.messageId); + const msg = Messages.findOneById(this.bodyParams.messageId); if (!msg) { throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); @@ -105,29 +108,29 @@ RocketChat.API.v1.addRoute('chat.pinMessage', { authRequired: true }, { let pinnedMessage; Meteor.runAsUser(this.userId, () => pinnedMessage = Meteor.call('pinMessage', msg)); - return RocketChat.API.v1.success({ - message: RocketChat.composeMessageObjectWithUser(pinnedMessage, this.userId), + return API.v1.success({ + message: composeMessageObjectWithUser(pinnedMessage, this.userId), }); }, }); -RocketChat.API.v1.addRoute('chat.postMessage', { authRequired: true }, { +API.v1.addRoute('chat.postMessage', { authRequired: true }, { post() { const messageReturn = processWebhookMessage(this.bodyParams, this.user, undefined, true)[0]; if (!messageReturn) { - return RocketChat.API.v1.failure('unknown-error'); + return API.v1.failure('unknown-error'); } - return RocketChat.API.v1.success({ + return API.v1.success({ ts: Date.now(), channel: messageReturn.channel, - message: RocketChat.composeMessageObjectWithUser(messageReturn.message, this.userId), + message: composeMessageObjectWithUser(messageReturn.message, this.userId), }); }, }); -RocketChat.API.v1.addRoute('chat.search', { authRequired: true }, { +API.v1.addRoute('chat.search', { authRequired: true }, { get() { const { roomId, searchText } = this.queryParams; const { count } = this.getPaginationItems(); @@ -143,8 +146,8 @@ RocketChat.API.v1.addRoute('chat.search', { authRequired: true }, { let result; Meteor.runAsUser(this.userId, () => result = Meteor.call('messageSearch', searchText, roomId, count).message.docs); - return RocketChat.API.v1.success({ - messages: result.map((message) => RocketChat.composeMessageObjectWithUser(message, this.userId)), + return API.v1.success({ + messages: result.map((message) => composeMessageObjectWithUser(message, this.userId)), }); }, }); @@ -152,7 +155,7 @@ RocketChat.API.v1.addRoute('chat.search', { authRequired: true }, { // The difference between `chat.postMessage` and `chat.sendMessage` is that `chat.sendMessage` allows // for passing a value for `_id` and the other one doesn't. Also, `chat.sendMessage` only sends it to // one channel whereas the other one allows for sending to more than one channel at a time. -RocketChat.API.v1.addRoute('chat.sendMessage', { authRequired: true }, { +API.v1.addRoute('chat.sendMessage', { authRequired: true }, { post() { if (!this.bodyParams.message) { throw new Meteor.Error('error-invalid-params', 'The "message" parameter must be provided.'); @@ -161,19 +164,19 @@ RocketChat.API.v1.addRoute('chat.sendMessage', { authRequired: true }, { let message; Meteor.runAsUser(this.userId, () => message = Meteor.call('sendMessage', this.bodyParams.message)); - return RocketChat.API.v1.success({ - message: RocketChat.composeMessageObjectWithUser(message, this.userId), + return API.v1.success({ + message: composeMessageObjectWithUser(message, this.userId), }); }, }); -RocketChat.API.v1.addRoute('chat.starMessage', { authRequired: true }, { +API.v1.addRoute('chat.starMessage', { authRequired: true }, { post() { if (!this.bodyParams.messageId || !this.bodyParams.messageId.trim()) { throw new Meteor.Error('error-messageid-param-not-provided', 'The required "messageId" param is required.'); } - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.messageId); + const msg = Messages.findOneById(this.bodyParams.messageId); if (!msg) { throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); @@ -185,17 +188,17 @@ RocketChat.API.v1.addRoute('chat.starMessage', { authRequired: true }, { starred: true, })); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('chat.unPinMessage', { authRequired: true }, { +API.v1.addRoute('chat.unPinMessage', { authRequired: true }, { post() { if (!this.bodyParams.messageId || !this.bodyParams.messageId.trim()) { throw new Meteor.Error('error-messageid-param-not-provided', 'The required "messageId" param is required.'); } - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.messageId); + const msg = Messages.findOneById(this.bodyParams.messageId); if (!msg) { throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); @@ -203,17 +206,17 @@ RocketChat.API.v1.addRoute('chat.unPinMessage', { authRequired: true }, { Meteor.runAsUser(this.userId, () => Meteor.call('unpinMessage', msg)); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('chat.unStarMessage', { authRequired: true }, { +API.v1.addRoute('chat.unStarMessage', { authRequired: true }, { post() { if (!this.bodyParams.messageId || !this.bodyParams.messageId.trim()) { throw new Meteor.Error('error-messageid-param-not-provided', 'The required "messageId" param is required.'); } - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.messageId); + const msg = Messages.findOneById(this.bodyParams.messageId); if (!msg) { throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); @@ -225,11 +228,11 @@ RocketChat.API.v1.addRoute('chat.unStarMessage', { authRequired: true }, { starred: false, })); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('chat.update', { authRequired: true }, { +API.v1.addRoute('chat.update', { authRequired: true }, { post() { check(this.bodyParams, Match.ObjectIncluding({ roomId: String, @@ -237,15 +240,15 @@ RocketChat.API.v1.addRoute('chat.update', { authRequired: true }, { text: String, // Using text to be consistant with chat.postMessage })); - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.msgId); + const msg = Messages.findOneById(this.bodyParams.msgId); // Ensure the message exists if (!msg) { - return RocketChat.API.v1.failure(`No message found with the id of "${ this.bodyParams.msgId }".`); + return API.v1.failure(`No message found with the id of "${ this.bodyParams.msgId }".`); } if (this.bodyParams.roomId !== msg.rid) { - return RocketChat.API.v1.failure('The room id provided does not match where the message is from.'); + return API.v1.failure('The room id provided does not match where the message is from.'); } // Permission checks are already done in the updateMessage method, so no need to duplicate them @@ -253,19 +256,19 @@ RocketChat.API.v1.addRoute('chat.update', { authRequired: true }, { Meteor.call('updateMessage', { _id: msg._id, msg: this.bodyParams.text, rid: msg.rid }); }); - return RocketChat.API.v1.success({ - message: RocketChat.composeMessageObjectWithUser(RocketChat.models.Messages.findOneById(msg._id), this.userId), + return API.v1.success({ + message: composeMessageObjectWithUser(Messages.findOneById(msg._id), this.userId), }); }, }); -RocketChat.API.v1.addRoute('chat.react', { authRequired: true }, { +API.v1.addRoute('chat.react', { authRequired: true }, { post() { if (!this.bodyParams.messageId || !this.bodyParams.messageId.trim()) { throw new Meteor.Error('error-messageid-param-not-provided', 'The required "messageId" param is missing.'); } - const msg = RocketChat.models.Messages.findOneById(this.bodyParams.messageId); + const msg = Messages.findOneById(this.bodyParams.messageId); if (!msg) { throw new Meteor.Error('error-message-not-found', 'The provided "messageId" does not match any existing message.'); @@ -279,50 +282,50 @@ RocketChat.API.v1.addRoute('chat.react', { authRequired: true }, { Meteor.runAsUser(this.userId, () => Meteor.call('setReaction', emoji, msg._id, this.bodyParams.shouldReact)); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('chat.getMessageReadReceipts', { authRequired: true }, { +API.v1.addRoute('chat.getMessageReadReceipts', { authRequired: true }, { get() { const { messageId } = this.queryParams; if (!messageId) { - return RocketChat.API.v1.failure({ + return API.v1.failure({ error: 'The required \'messageId\' param is missing.', }); } try { const messageReadReceipts = Meteor.runAsUser(this.userId, () => Meteor.call('getReadReceipts', { messageId })); - return RocketChat.API.v1.success({ + return API.v1.success({ receipts: messageReadReceipts, }); } catch (error) { - return RocketChat.API.v1.failure({ + return API.v1.failure({ error: error.message, }); } }, }); -RocketChat.API.v1.addRoute('chat.reportMessage', { authRequired: true }, { +API.v1.addRoute('chat.reportMessage', { authRequired: true }, { post() { const { messageId, description } = this.bodyParams; if (!messageId) { - return RocketChat.API.v1.failure('The required "messageId" param is missing.'); + return API.v1.failure('The required "messageId" param is missing.'); } if (!description) { - return RocketChat.API.v1.failure('The required "description" param is missing.'); + return API.v1.failure('The required "description" param is missing.'); } Meteor.runAsUser(this.userId, () => Meteor.call('reportMessage', messageId, description)); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('chat.ignoreUser', { authRequired: true }, { +API.v1.addRoute('chat.ignoreUser', { authRequired: true }, { get() { const { rid, userId } = this.queryParams; let { ignore = true } = this.queryParams; @@ -339,11 +342,11 @@ RocketChat.API.v1.addRoute('chat.ignoreUser', { authRequired: true }, { Meteor.runAsUser(this.userId, () => Meteor.call('ignoreUser', { rid, userId, ignore })); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('chat.getDeletedMessages', { authRequired: true }, { +API.v1.addRoute('chat.getDeletedMessages', { authRequired: true }, { get() { const { roomId, since } = this.queryParams; const { offset, count } = this.getPaginationItems(); @@ -357,7 +360,7 @@ RocketChat.API.v1.addRoute('chat.getDeletedMessages', { authRequired: true }, { } else if (isNaN(Date.parse(since))) { throw new Meteor.Error('The "since" query parameter must be a valid date.'); } - const cursor = RocketChat.models.Messages.trashFindDeletedAfter(new Date(since), { rid: roomId }, { + const cursor = Messages.trashFindDeletedAfter(new Date(since), { rid: roomId }, { skip: offset, limit: count, fields: { _id: 1 }, @@ -367,7 +370,7 @@ RocketChat.API.v1.addRoute('chat.getDeletedMessages', { authRequired: true }, { const messages = cursor.fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ messages, count: messages.length, offset, diff --git a/packages/rocketchat-api/server/v1/commands.js b/packages/rocketchat-api/server/v1/commands.js index bfac0b17d5aa..3fdd8f042c47 100644 --- a/packages/rocketchat-api/server/v1/commands.js +++ b/packages/rocketchat-api/server/v1/commands.js @@ -1,45 +1,47 @@ import { Meteor } from 'meteor/meteor'; import { Random } from 'meteor/random'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { slashCommands } from 'meteor/rocketchat:utils'; +import { Rooms } from 'meteor/rocketchat:models'; +import { API } from '../api'; -RocketChat.API.v1.addRoute('commands.get', { authRequired: true }, { +API.v1.addRoute('commands.get', { authRequired: true }, { get() { const params = this.queryParams; if (typeof params.command !== 'string') { - return RocketChat.API.v1.failure('The query param "command" must be provided.'); + return API.v1.failure('The query param "command" must be provided.'); } - const cmd = RocketChat.slashCommands.commands[params.command.toLowerCase()]; + const cmd = slashCommands.commands[params.command.toLowerCase()]; if (!cmd) { - return RocketChat.API.v1.failure(`There is no command in the system by the name of: ${ params.command }`); + return API.v1.failure(`There is no command in the system by the name of: ${ params.command }`); } - return RocketChat.API.v1.success({ command: cmd }); + return API.v1.success({ command: cmd }); }, }); -RocketChat.API.v1.addRoute('commands.list', { authRequired: true }, { +API.v1.addRoute('commands.list', { authRequired: true }, { get() { const { offset, count } = this.getPaginationItems(); const { sort, fields, query } = this.parseJsonQuery(); - let commands = Object.values(RocketChat.slashCommands.commands); + let commands = Object.values(slashCommands.commands); if (query && query.command) { commands = commands.filter((command) => command.command === query.command); } const totalCount = commands.length; - commands = RocketChat.models.Rooms.processQueryOptionsOnResult(commands, { + commands = Rooms.processQueryOptionsOnResult(commands, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, fields, }); - return RocketChat.API.v1.success({ + return API.v1.success({ commands, offset, count: commands.length, @@ -49,26 +51,26 @@ RocketChat.API.v1.addRoute('commands.list', { authRequired: true }, { }); // Expects a body of: { command: 'gimme', params: 'any string value', roomId: 'value' } -RocketChat.API.v1.addRoute('commands.run', { authRequired: true }, { +API.v1.addRoute('commands.run', { authRequired: true }, { post() { const body = this.bodyParams; const user = this.getLoggedInUser(); if (typeof body.command !== 'string') { - return RocketChat.API.v1.failure('You must provide a command to run.'); + return API.v1.failure('You must provide a command to run.'); } if (body.params && typeof body.params !== 'string') { - return RocketChat.API.v1.failure('The parameters for the command must be a single string.'); + return API.v1.failure('The parameters for the command must be a single string.'); } if (typeof body.roomId !== 'string') { - return RocketChat.API.v1.failure('The room\'s id where to execute this command must be provided and be a string.'); + return API.v1.failure('The room\'s id where to execute this command must be provided and be a string.'); } const cmd = body.command.toLowerCase(); - if (!RocketChat.slashCommands.commands[body.command.toLowerCase()]) { - return RocketChat.API.v1.failure('The command provided does not exist (or is disabled).'); + if (!slashCommands.commands[body.command.toLowerCase()]) { + return API.v1.failure('The command provided does not exist (or is disabled).'); } // This will throw an error if they can't or the room is invalid @@ -78,38 +80,38 @@ RocketChat.API.v1.addRoute('commands.run', { authRequired: true }, { let result; Meteor.runAsUser(user._id, () => { - result = RocketChat.slashCommands.run(cmd, params, { + result = slashCommands.run(cmd, params, { _id: Random.id(), rid: body.roomId, msg: `/${ cmd } ${ params }`, }); }); - return RocketChat.API.v1.success({ result }); + return API.v1.success({ result }); }, }); -RocketChat.API.v1.addRoute('commands.preview', { authRequired: true }, { +API.v1.addRoute('commands.preview', { authRequired: true }, { // Expects these query params: command: 'giphy', params: 'mine', roomId: 'value' get() { const query = this.queryParams; const user = this.getLoggedInUser(); if (typeof query.command !== 'string') { - return RocketChat.API.v1.failure('You must provide a command to get the previews from.'); + return API.v1.failure('You must provide a command to get the previews from.'); } if (query.params && typeof query.params !== 'string') { - return RocketChat.API.v1.failure('The parameters for the command must be a single string.'); + return API.v1.failure('The parameters for the command must be a single string.'); } if (typeof query.roomId !== 'string') { - return RocketChat.API.v1.failure('The room\'s id where the previews are being displayed must be provided and be a string.'); + return API.v1.failure('The room\'s id where the previews are being displayed must be provided and be a string.'); } const cmd = query.command.toLowerCase(); - if (!RocketChat.slashCommands.commands[cmd]) { - return RocketChat.API.v1.failure('The command provided does not exist (or is disabled).'); + if (!slashCommands.commands[cmd]) { + return API.v1.failure('The command provided does not exist (or is disabled).'); } // This will throw an error if they can't or the room is invalid @@ -122,7 +124,7 @@ RocketChat.API.v1.addRoute('commands.preview', { authRequired: true }, { preview = Meteor.call('getSlashCommandPreviews', { cmd, params, msg: { rid: query.roomId } }); }); - return RocketChat.API.v1.success({ preview }); + return API.v1.success({ preview }); }, // Expects a body format of: { command: 'giphy', params: 'mine', roomId: 'value', previewItem: { id: 'sadf8' type: 'image', value: 'https://dev.null/gif } } post() { @@ -130,28 +132,28 @@ RocketChat.API.v1.addRoute('commands.preview', { authRequired: true }, { const user = this.getLoggedInUser(); if (typeof body.command !== 'string') { - return RocketChat.API.v1.failure('You must provide a command to run the preview item on.'); + return API.v1.failure('You must provide a command to run the preview item on.'); } if (body.params && typeof body.params !== 'string') { - return RocketChat.API.v1.failure('The parameters for the command must be a single string.'); + return API.v1.failure('The parameters for the command must be a single string.'); } if (typeof body.roomId !== 'string') { - return RocketChat.API.v1.failure('The room\'s id where the preview is being executed in must be provided and be a string.'); + return API.v1.failure('The room\'s id where the preview is being executed in must be provided and be a string.'); } if (typeof body.previewItem === 'undefined') { - return RocketChat.API.v1.failure('The preview item being executed must be provided.'); + return API.v1.failure('The preview item being executed must be provided.'); } if (!body.previewItem.id || !body.previewItem.type || typeof body.previewItem.value === 'undefined') { - return RocketChat.API.v1.failure('The preview item being executed is in the wrong format.'); + return API.v1.failure('The preview item being executed is in the wrong format.'); } const cmd = body.command.toLowerCase(); - if (!RocketChat.slashCommands.commands[cmd]) { - return RocketChat.API.v1.failure('The command provided does not exist (or is disabled).'); + if (!slashCommands.commands[cmd]) { + return API.v1.failure('The command provided does not exist (or is disabled).'); } // This will throw an error if they can't or the room is invalid @@ -163,6 +165,6 @@ RocketChat.API.v1.addRoute('commands.preview', { authRequired: true }, { Meteor.call('executeSlashCommandPreview', { cmd, params, msg: { rid: body.roomId } }, body.previewItem); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); diff --git a/packages/rocketchat-api/server/v1/e2e.js b/packages/rocketchat-api/server/v1/e2e.js index f21f55e6e294..c4974add4774 100644 --- a/packages/rocketchat-api/server/v1/e2e.js +++ b/packages/rocketchat-api/server/v1/e2e.js @@ -1,61 +1,61 @@ import { Meteor } from 'meteor/meteor'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { API } from '../api'; -RocketChat.API.v1.addRoute('e2e.fetchMyKeys', { authRequired: true }, { +API.v1.addRoute('e2e.fetchMyKeys', { authRequired: true }, { get() { let result; Meteor.runAsUser(this.userId, () => result = Meteor.call('e2e.fetchMyKeys')); - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); -RocketChat.API.v1.addRoute('e2e.getUsersOfRoomWithoutKey', { authRequired: true }, { +API.v1.addRoute('e2e.getUsersOfRoomWithoutKey', { authRequired: true }, { get() { const { rid } = this.queryParams; let result; Meteor.runAsUser(this.userId, () => result = Meteor.call('e2e.getUsersOfRoomWithoutKey', rid)); - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); -RocketChat.API.v1.addRoute('e2e.setRoomKeyID', { authRequired: true }, { +API.v1.addRoute('e2e.setRoomKeyID', { authRequired: true }, { post() { const { rid, keyID } = this.bodyParams; Meteor.runAsUser(this.userId, () => { - RocketChat.API.v1.success(Meteor.call('e2e.setRoomKeyID', rid, keyID)); + API.v1.success(Meteor.call('e2e.setRoomKeyID', rid, keyID)); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('e2e.setUserPublicAndPivateKeys', { authRequired: true }, { +API.v1.addRoute('e2e.setUserPublicAndPivateKeys', { authRequired: true }, { post() { const { public_key, private_key } = this.bodyParams; Meteor.runAsUser(this.userId, () => { - RocketChat.API.v1.success(Meteor.call('e2e.setUserPublicAndPivateKeys', { + API.v1.success(Meteor.call('e2e.setUserPublicAndPivateKeys', { public_key, private_key, })); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('e2e.updateGroupKey', { authRequired: true }, { +API.v1.addRoute('e2e.updateGroupKey', { authRequired: true }, { post() { const { uid, rid, key } = this.bodyParams; Meteor.runAsUser(this.userId, () => { - RocketChat.API.v1.success(Meteor.call('e2e.updateGroupKey', rid, uid, key)); + API.v1.success(Meteor.call('e2e.updateGroupKey', rid, uid, key)); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); diff --git a/packages/rocketchat-api/server/v1/emoji-custom.js b/packages/rocketchat-api/server/v1/emoji-custom.js index 10ebcb64bb27..43bf3a6a84eb 100644 --- a/packages/rocketchat-api/server/v1/emoji-custom.js +++ b/packages/rocketchat-api/server/v1/emoji-custom.js @@ -1,17 +1,18 @@ import { Meteor } from 'meteor/meteor'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { EmojiCustom } from 'meteor/rocketchat:models'; +import { API } from '../api'; import Busboy from 'busboy'; -RocketChat.API.v1.addRoute('emoji-custom', { authRequired: true }, { +API.v1.addRoute('emoji-custom', { authRequired: true }, { get() { const { query } = this.parseJsonQuery(); const emojis = Meteor.call('listEmojiCustom', query); - return RocketChat.API.v1.success({ emojis }); + return API.v1.success({ emojis }); }, }); -RocketChat.API.v1.addRoute('emoji-custom.create', { authRequired: true }, { +API.v1.addRoute('emoji-custom.create', { authRequired: true }, { post() { Meteor.runAsUser(this.userId, () => { const fields = {}; @@ -53,7 +54,7 @@ RocketChat.API.v1.addRoute('emoji-custom.create', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('emoji-custom.update', { authRequired: true }, { +API.v1.addRoute('emoji-custom.update', { authRequired: true }, { post() { Meteor.runAsUser(this.userId, () => { const fields = {}; @@ -82,7 +83,7 @@ RocketChat.API.v1.addRoute('emoji-custom.update', { authRequired: true }, { if (!fields._id) { return callback(new Meteor.Error('The required "_id" query param is missing.')); } - const emojiToUpdate = RocketChat.models.EmojiCustom.findOneByID(fields._id); + const emojiToUpdate = EmojiCustom.findOneByID(fields._id); if (!emojiToUpdate) { return callback(new Meteor.Error('Emoji not found.')); } @@ -106,15 +107,15 @@ RocketChat.API.v1.addRoute('emoji-custom.update', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('emoji-custom.delete', { authRequired: true }, { +API.v1.addRoute('emoji-custom.delete', { authRequired: true }, { post() { const { emojiId } = this.bodyParams; if (!emojiId) { - return RocketChat.API.v1.failure('The "emojiId" params is required!'); + return API.v1.failure('The "emojiId" params is required!'); } Meteor.runAsUser(this.userId, () => Meteor.call('deleteEmojiCustom', emojiId)); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); diff --git a/packages/rocketchat-api/server/v1/groups.js b/packages/rocketchat-api/server/v1/groups.js index fc5430c1f6ce..96c23e42e726 100644 --- a/packages/rocketchat-api/server/v1/groups.js +++ b/packages/rocketchat-api/server/v1/groups.js @@ -1,5 +1,8 @@ import { Meteor } from 'meteor/meteor'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { Subscriptions, Rooms, Messages, Uploads, Integrations, Users } from 'meteor/rocketchat:models'; +import { hasPermission } from 'meteor/rocketchat:authorization'; +import { composeMessageObjectWithUser } from 'meteor/rocketchat:utils'; +import { API } from '../api'; import _ from 'underscore'; // Returns the private group subscription IF found otherwise it will return the failure of why it didn't. Check the `statusCode` property @@ -10,9 +13,9 @@ function findPrivateGroupByIdOrName({ params, userId, checkedArchived = true }) let roomSub; if (params.roomId) { - roomSub = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(params.roomId, userId); + roomSub = Subscriptions.findOneByRoomIdAndUserId(params.roomId, userId); } else if (params.roomName) { - roomSub = RocketChat.models.Subscriptions.findOneByRoomNameAndUserId(params.roomName, userId); + roomSub = Subscriptions.findOneByRoomNameAndUserId(params.roomName, userId); } if (!roomSub || roomSub.t !== 'p') { @@ -26,7 +29,7 @@ function findPrivateGroupByIdOrName({ params, userId, checkedArchived = true }) return roomSub; } -RocketChat.API.v1.addRoute('groups.addAll', { authRequired: true }, { +API.v1.addRoute('groups.addAll', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -34,13 +37,13 @@ RocketChat.API.v1.addRoute('groups.addAll', { authRequired: true }, { Meteor.call('addAllUserToRoom', findResult.rid, this.bodyParams.activeUsersOnly); }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(findResult.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.addModerator', { authRequired: true }, { +API.v1.addRoute('groups.addModerator', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -50,11 +53,11 @@ RocketChat.API.v1.addRoute('groups.addModerator', { authRequired: true }, { Meteor.call('addRoomModerator', findResult.rid, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.addOwner', { authRequired: true }, { +API.v1.addRoute('groups.addOwner', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -64,11 +67,11 @@ RocketChat.API.v1.addRoute('groups.addOwner', { authRequired: true }, { Meteor.call('addRoomOwner', findResult.rid, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.addLeader', { authRequired: true }, { +API.v1.addRoute('groups.addLeader', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); const user = this.getUserFromParams(); @@ -76,12 +79,12 @@ RocketChat.API.v1.addRoute('groups.addLeader', { authRequired: true }, { Meteor.call('addRoomLeader', findResult.rid, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); // Archives a private group only if it wasn't -RocketChat.API.v1.addRoute('groups.archive', { authRequired: true }, { +API.v1.addRoute('groups.archive', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -89,29 +92,29 @@ RocketChat.API.v1.addRoute('groups.archive', { authRequired: true }, { Meteor.call('archiveRoom', findResult.rid); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.close', { authRequired: true }, { +API.v1.addRoute('groups.close', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); if (!findResult.open) { - return RocketChat.API.v1.failure(`The private group, ${ findResult.name }, is already closed to the sender`); + return API.v1.failure(`The private group, ${ findResult.name }, is already closed to the sender`); } Meteor.runAsUser(this.userId, () => { Meteor.call('hideRoom', findResult.rid); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.counters', { authRequired: true }, { +API.v1.addRoute('groups.counters', { authRequired: true }, { get() { - const access = RocketChat.authz.hasPermission(this.userId, 'view-room-administration'); + const access = hasPermission(this.userId, 'view-room-administration'); const params = this.requestParams(); let user = this.userId; let room; @@ -128,9 +131,9 @@ RocketChat.API.v1.addRoute('groups.counters', { authRequired: true }, { } if (params.roomId) { - room = RocketChat.models.Rooms.findOneById(params.roomId); + room = Rooms.findOneById(params.roomId); } else if (params.roomName) { - room = RocketChat.models.Rooms.findOneByName(params.roomName); + room = Rooms.findOneByName(params.roomName); } if (!room || room.t !== 'p') { @@ -143,15 +146,15 @@ RocketChat.API.v1.addRoute('groups.counters', { authRequired: true }, { if (params.userId) { if (!access) { - return RocketChat.API.v1.unauthorized(); + return API.v1.unauthorized(); } user = params.userId; } - const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user); + const subscription = Subscriptions.findOneByRoomIdAndUserId(room._id, user); const lm = room.lm ? room.lm : room._updatedAt; if (typeof subscription !== 'undefined' && subscription.open) { - unreads = RocketChat.models.Messages.countVisibleByRoomIdBetweenTimestampsInclusive(subscription.rid, (subscription.ls || subscription.ts), lm); + unreads = Messages.countVisibleByRoomIdBetweenTimestampsInclusive(subscription.rid, (subscription.ls || subscription.ts), lm); unreadsFrom = subscription.ls || subscription.ts; userMentions = subscription.userMentions; joined = true; @@ -163,7 +166,7 @@ RocketChat.API.v1.addRoute('groups.counters', { authRequired: true }, { members = room.usersCount; } - return RocketChat.API.v1.success({ + return API.v1.success({ joined, members, unreads, @@ -176,22 +179,22 @@ RocketChat.API.v1.addRoute('groups.counters', { authRequired: true }, { }); // Create Private Group -RocketChat.API.v1.addRoute('groups.create', { authRequired: true }, { +API.v1.addRoute('groups.create', { authRequired: true }, { post() { - if (!RocketChat.authz.hasPermission(this.userId, 'create-p')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'create-p')) { + return API.v1.unauthorized(); } if (!this.bodyParams.name) { - return RocketChat.API.v1.failure('Body param "name" is required'); + return API.v1.failure('Body param "name" is required'); } if (this.bodyParams.members && !_.isArray(this.bodyParams.members)) { - return RocketChat.API.v1.failure('Body param "members" must be an array if provided'); + return API.v1.failure('Body param "members" must be an array if provided'); } if (this.bodyParams.customFields && !(typeof this.bodyParams.customFields === 'object')) { - return RocketChat.API.v1.failure('Body param "customFields" must be an object if provided'); + return API.v1.failure('Body param "customFields" must be an object if provided'); } const readOnly = typeof this.bodyParams.readOnly !== 'undefined' ? this.bodyParams.readOnly : false; @@ -201,13 +204,13 @@ RocketChat.API.v1.addRoute('groups.create', { authRequired: true }, { id = Meteor.call('createPrivateGroup', this.bodyParams.name, this.bodyParams.members ? this.bodyParams.members : [], readOnly, this.bodyParams.customFields); }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(id.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(id.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.delete', { authRequired: true }, { +API.v1.addRoute('groups.delete', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); @@ -215,11 +218,11 @@ RocketChat.API.v1.addRoute('groups.delete', { authRequired: true }, { Meteor.call('eraseRoom', findResult.rid); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.files', { authRequired: true }, { +API.v1.addRoute('groups.files', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); const addUserObjectToEveryObject = (file) => { @@ -234,26 +237,26 @@ RocketChat.API.v1.addRoute('groups.files', { authRequired: true }, { const ourQuery = Object.assign({}, query, { rid: findResult.rid }); - const files = RocketChat.models.Uploads.find(ourQuery, { + const files = Uploads.find(ourQuery, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ files: files.map(addUserObjectToEveryObject), count: files.length, offset, - total: RocketChat.models.Uploads.find(ourQuery).count(), + total: Uploads.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute('groups.getIntegrations', { authRequired: true }, { +API.v1.addRoute('groups.getIntegrations', { authRequired: true }, { get() { - if (!RocketChat.authz.hasPermission(this.userId, 'manage-integrations')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'manage-integrations')) { + return API.v1.unauthorized(); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); @@ -272,23 +275,23 @@ RocketChat.API.v1.addRoute('groups.getIntegrations', { authRequired: true }, { const { sort, fields, query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query, { channel: { $in: channelsToSearch } }); - const integrations = RocketChat.models.Integrations.find(ourQuery, { + const integrations = Integrations.find(ourQuery, { sort: sort ? sort : { _createdAt: 1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ integrations, count: integrations.length, offset, - total: RocketChat.models.Integrations.find(ourQuery).count(), + total: Integrations.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute('groups.history', { authRequired: true }, { +API.v1.addRoute('groups.history', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); @@ -317,24 +320,24 @@ RocketChat.API.v1.addRoute('groups.history', { authRequired: true }, { }); if (!result) { - return RocketChat.API.v1.unauthorized(); + return API.v1.unauthorized(); } - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); -RocketChat.API.v1.addRoute('groups.info', { authRequired: true }, { +API.v1.addRoute('groups.info', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(findResult.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.invite', { authRequired: true }, { +API.v1.addRoute('groups.invite', { authRequired: true }, { post() { const { roomId = '', roomName = '' } = this.requestParams(); const idOrName = roomId || roomName; @@ -342,7 +345,7 @@ RocketChat.API.v1.addRoute('groups.invite', { authRequired: true }, { throw new Meteor.Error('error-room-param-not-provided', 'The parameter "roomId" or "roomName" is required'); } - const { _id: rid, t: type } = RocketChat.models.Rooms.findOneByIdOrName(idOrName) || {}; + const { _id: rid, t: type } = Rooms.findOneByIdOrName(idOrName) || {}; if (!rid || type !== 'p') { throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "roomName" param provided does not match any group'); @@ -352,13 +355,13 @@ RocketChat.API.v1.addRoute('groups.invite', { authRequired: true }, { Meteor.runAsUser(this.userId, () => Meteor.call('addUserToRoom', { rid, username })); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.kick', { authRequired: true }, { +API.v1.addRoute('groups.kick', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -368,11 +371,11 @@ RocketChat.API.v1.addRoute('groups.kick', { authRequired: true }, { Meteor.call('removeUserFromRoom', { rid: findResult.rid, username: user.username }); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.leave', { authRequired: true }, { +API.v1.addRoute('groups.leave', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -380,18 +383,18 @@ RocketChat.API.v1.addRoute('groups.leave', { authRequired: true }, { Meteor.call('leaveRoom', findResult.rid); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); // List Private Groups a user has access to -RocketChat.API.v1.addRoute('groups.list', { authRequired: true }, { +API.v1.addRoute('groups.list', { authRequired: true }, { get() { const { offset, count } = this.getPaginationItems(); const { sort, fields } = this.parseJsonQuery(); // TODO: CACHE: Add Breacking notice since we removed the query param - const cursor = RocketChat.models.Rooms.findBySubscriptionTypeAndUserId('p', this.userId, { + const cursor = Rooms.findBySubscriptionTypeAndUserId('p', this.userId, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, @@ -402,7 +405,7 @@ RocketChat.API.v1.addRoute('groups.list', { authRequired: true }, { const rooms = cursor.fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ groups: rooms.map((room) => this.composeRoomWithLastMessage(room, this.userId)), offset, count: rooms.length, @@ -412,26 +415,26 @@ RocketChat.API.v1.addRoute('groups.list', { authRequired: true }, { }); -RocketChat.API.v1.addRoute('groups.listAll', { authRequired: true }, { +API.v1.addRoute('groups.listAll', { authRequired: true }, { get() { - if (!RocketChat.authz.hasPermission(this.userId, 'view-room-administration')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'view-room-administration')) { + return API.v1.unauthorized(); } const { offset, count } = this.getPaginationItems(); const { sort, fields, query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query, { t: 'p' }); - let rooms = RocketChat.models.Rooms.find(ourQuery).fetch(); + let rooms = Rooms.find(ourQuery).fetch(); const totalCount = rooms.length; - rooms = RocketChat.models.Rooms.processQueryOptionsOnResult(rooms, { + rooms = Rooms.processQueryOptionsOnResult(rooms, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, fields, }); - return RocketChat.API.v1.success({ + return API.v1.success({ groups: rooms.map((room) => this.composeRoomWithLastMessage(room, this.userId)), offset, count: rooms.length, @@ -440,19 +443,19 @@ RocketChat.API.v1.addRoute('groups.listAll', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('groups.members', { authRequired: true }, { +API.v1.addRoute('groups.members', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); - const room = RocketChat.models.Rooms.findOneById(findResult.rid, { fields: { broadcast: 1 } }); + const room = Rooms.findOneById(findResult.rid, { fields: { broadcast: 1 } }); - if (room.broadcast && !RocketChat.authz.hasPermission(this.userId, 'view-broadcast-member-list')) { - return RocketChat.API.v1.unauthorized(); + if (room.broadcast && !hasPermission(this.userId, 'view-broadcast-member-list')) { + return API.v1.unauthorized(); } const { offset, count } = this.getPaginationItems(); const { sort = {} } = this.parseJsonQuery(); - const subscriptions = RocketChat.models.Subscriptions.findByRoomId(findResult.rid, { + const subscriptions = Subscriptions.findByRoomId(findResult.rid, { fields: { 'u._id': 1 }, sort: { 'u.username': sort.username != null ? sort.username : 1 }, skip: offset, @@ -463,12 +466,12 @@ RocketChat.API.v1.addRoute('groups.members', { authRequired: true }, { const members = subscriptions.fetch().map((s) => s.u && s.u._id); - const users = RocketChat.models.Users.find({ _id: { $in: members } }, { + const users = Users.find({ _id: { $in: members } }, { fields: { _id: 1, username: 1, name: 1, status: 1, utcOffset: 1 }, sort: { username: sort.username != null ? sort.username : 1 }, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ members: users, count: users.length, offset, @@ -477,7 +480,7 @@ RocketChat.API.v1.addRoute('groups.members', { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute('groups.messages', { authRequired: true }, { +API.v1.addRoute('groups.messages', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); const { offset, count } = this.getPaginationItems(); @@ -485,34 +488,34 @@ RocketChat.API.v1.addRoute('groups.messages', { authRequired: true }, { const ourQuery = Object.assign({}, query, { rid: findResult.rid }); - const messages = RocketChat.models.Messages.find(ourQuery, { + const messages = Messages.find(ourQuery, { sort: sort ? sort : { ts: -1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ - messages: messages.map((message) => RocketChat.composeMessageObjectWithUser(message, this.userId)), + return API.v1.success({ + messages: messages.map((message) => composeMessageObjectWithUser(message, this.userId)), count: messages.length, offset, - total: RocketChat.models.Messages.find(ourQuery).count(), + total: Messages.find(ourQuery).count(), }); }, }); // TODO: CACHE: same as channels.online -RocketChat.API.v1.addRoute('groups.online', { authRequired: true }, { +API.v1.addRoute('groups.online', { authRequired: true }, { get() { const { query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query, { t: 'p' }); - const room = RocketChat.models.Rooms.findOne(ourQuery); + const room = Rooms.findOne(ourQuery); if (room == null) { - return RocketChat.API.v1.failure('Group does not exists'); + return API.v1.failure('Group does not exists'); } - const online = RocketChat.models.Users.findUsersNotOffline({ + const online = Users.findUsersNotOffline({ fields: { username: 1, }, @@ -520,7 +523,7 @@ RocketChat.API.v1.addRoute('groups.online', { authRequired: true }, { const onlineInRoom = []; online.forEach((user) => { - const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, { fields: { _id: 1 } }); + const subscription = Subscriptions.findOneByRoomIdAndUserId(room._id, user._id, { fields: { _id: 1 } }); if (subscription) { onlineInRoom.push({ _id: user._id, @@ -529,29 +532,29 @@ RocketChat.API.v1.addRoute('groups.online', { authRequired: true }, { } }); - return RocketChat.API.v1.success({ + return API.v1.success({ online: onlineInRoom, }); }, }); -RocketChat.API.v1.addRoute('groups.open', { authRequired: true }, { +API.v1.addRoute('groups.open', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); if (findResult.open) { - return RocketChat.API.v1.failure(`The private group, ${ findResult.name }, is already open for the sender`); + return API.v1.failure(`The private group, ${ findResult.name }, is already open for the sender`); } Meteor.runAsUser(this.userId, () => { Meteor.call('openRoom', findResult.rid); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.removeModerator', { authRequired: true }, { +API.v1.addRoute('groups.removeModerator', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -561,11 +564,11 @@ RocketChat.API.v1.addRoute('groups.removeModerator', { authRequired: true }, { Meteor.call('removeRoomModerator', findResult.rid, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.removeOwner', { authRequired: true }, { +API.v1.addRoute('groups.removeOwner', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -575,11 +578,11 @@ RocketChat.API.v1.addRoute('groups.removeOwner', { authRequired: true }, { Meteor.call('removeRoomOwner', findResult.rid, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.removeLeader', { authRequired: true }, { +API.v1.addRoute('groups.removeLeader', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -589,14 +592,14 @@ RocketChat.API.v1.addRoute('groups.removeLeader', { authRequired: true }, { Meteor.call('removeRoomLeader', findResult.rid, user._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.rename', { authRequired: true }, { +API.v1.addRoute('groups.rename', { authRequired: true }, { post() { if (!this.bodyParams.name || !this.bodyParams.name.trim()) { - return RocketChat.API.v1.failure('The bodyParam "name" is required'); + return API.v1.failure('The bodyParam "name" is required'); } const findResult = findPrivateGroupByIdOrName({ params: { roomId: this.bodyParams.roomId }, userId: this.userId }); @@ -605,16 +608,16 @@ RocketChat.API.v1.addRoute('groups.rename', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult.rid, 'roomName', this.bodyParams.name); }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(findResult.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.setCustomFields', { authRequired: true }, { +API.v1.addRoute('groups.setCustomFields', { authRequired: true }, { post() { if (!this.bodyParams.customFields || !(typeof this.bodyParams.customFields === 'object')) { - return RocketChat.API.v1.failure('The bodyParam "customFields" is required with a type like object.'); + return API.v1.failure('The bodyParam "customFields" is required with a type like object.'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -623,16 +626,16 @@ RocketChat.API.v1.addRoute('groups.setCustomFields', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult.rid, 'roomCustomFields', this.bodyParams.customFields); }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(findResult.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.setDescription', { authRequired: true }, { +API.v1.addRoute('groups.setDescription', { authRequired: true }, { post() { if (!this.bodyParams.description || !this.bodyParams.description.trim()) { - return RocketChat.API.v1.failure('The bodyParam "description" is required'); + return API.v1.failure('The bodyParam "description" is required'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -641,16 +644,16 @@ RocketChat.API.v1.addRoute('groups.setDescription', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult.rid, 'roomDescription', this.bodyParams.description); }); - return RocketChat.API.v1.success({ + return API.v1.success({ description: this.bodyParams.description, }); }, }); -RocketChat.API.v1.addRoute('groups.setPurpose', { authRequired: true }, { +API.v1.addRoute('groups.setPurpose', { authRequired: true }, { post() { if (!this.bodyParams.purpose || !this.bodyParams.purpose.trim()) { - return RocketChat.API.v1.failure('The bodyParam "purpose" is required'); + return API.v1.failure('The bodyParam "purpose" is required'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -659,38 +662,38 @@ RocketChat.API.v1.addRoute('groups.setPurpose', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult.rid, 'roomDescription', this.bodyParams.purpose); }); - return RocketChat.API.v1.success({ + return API.v1.success({ purpose: this.bodyParams.purpose, }); }, }); -RocketChat.API.v1.addRoute('groups.setReadOnly', { authRequired: true }, { +API.v1.addRoute('groups.setReadOnly', { authRequired: true }, { post() { if (typeof this.bodyParams.readOnly === 'undefined') { - return RocketChat.API.v1.failure('The bodyParam "readOnly" is required'); + return API.v1.failure('The bodyParam "readOnly" is required'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); if (findResult.ro === this.bodyParams.readOnly) { - return RocketChat.API.v1.failure('The private group read only setting is the same as what it would be changed to.'); + return API.v1.failure('The private group read only setting is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult.rid, 'readOnly', this.bodyParams.readOnly); }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(findResult.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.setTopic', { authRequired: true }, { +API.v1.addRoute('groups.setTopic', { authRequired: true }, { post() { if (!this.bodyParams.topic || !this.bodyParams.topic.trim()) { - return RocketChat.API.v1.failure('The bodyParam "topic" is required'); + return API.v1.failure('The bodyParam "topic" is required'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -699,38 +702,38 @@ RocketChat.API.v1.addRoute('groups.setTopic', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult.rid, 'roomTopic', this.bodyParams.topic); }); - return RocketChat.API.v1.success({ + return API.v1.success({ topic: this.bodyParams.topic, }); }, }); -RocketChat.API.v1.addRoute('groups.setType', { authRequired: true }, { +API.v1.addRoute('groups.setType', { authRequired: true }, { post() { if (!this.bodyParams.type || !this.bodyParams.type.trim()) { - return RocketChat.API.v1.failure('The bodyParam "type" is required'); + return API.v1.failure('The bodyParam "type" is required'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); if (findResult.t === this.bodyParams.type) { - return RocketChat.API.v1.failure('The private group type is the same as what it would be changed to.'); + return API.v1.failure('The private group type is the same as what it would be changed to.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('saveRoomSettings', findResult.rid, 'roomType', this.bodyParams.type); }); - return RocketChat.API.v1.success({ - group: this.composeRoomWithLastMessage(RocketChat.models.Rooms.findOneById(findResult.rid, { fields: RocketChat.API.v1.defaultFieldsToExclude }), this.userId), + return API.v1.success({ + group: this.composeRoomWithLastMessage(Rooms.findOneById(findResult.rid, { fields: API.v1.defaultFieldsToExclude }), this.userId), }); }, }); -RocketChat.API.v1.addRoute('groups.setAnnouncement', { authRequired: true }, { +API.v1.addRoute('groups.setAnnouncement', { authRequired: true }, { post() { if (!this.bodyParams.announcement || !this.bodyParams.announcement.trim()) { - return RocketChat.API.v1.failure('The bodyParam "announcement" is required'); + return API.v1.failure('The bodyParam "announcement" is required'); } const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); @@ -739,13 +742,13 @@ RocketChat.API.v1.addRoute('groups.setAnnouncement', { authRequired: true }, { Meteor.call('saveRoomSettings', findResult.rid, 'roomAnnouncement', this.bodyParams.announcement); }); - return RocketChat.API.v1.success({ + return API.v1.success({ announcement: this.bodyParams.announcement, }); }, }); -RocketChat.API.v1.addRoute('groups.unarchive', { authRequired: true }, { +API.v1.addRoute('groups.unarchive', { authRequired: true }, { post() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId, checkedArchived: false }); @@ -753,29 +756,29 @@ RocketChat.API.v1.addRoute('groups.unarchive', { authRequired: true }, { Meteor.call('unarchiveRoom', findResult.rid); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('groups.roles', { authRequired: true }, { +API.v1.addRoute('groups.roles', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); const roles = Meteor.runAsUser(this.userId, () => Meteor.call('getRoomRoles', findResult.rid)); - return RocketChat.API.v1.success({ + return API.v1.success({ roles, }); }, }); -RocketChat.API.v1.addRoute('groups.moderators', { authRequired: true }, { +API.v1.addRoute('groups.moderators', { authRequired: true }, { get() { const findResult = findPrivateGroupByIdOrName({ params: this.requestParams(), userId: this.userId }); - const moderators = RocketChat.models.Subscriptions.findByRoomIdAndRoles(findResult.rid, ['moderator'], { fields: { u: 1 } }).fetch().map((sub) => sub.u); + const moderators = Subscriptions.findByRoomIdAndRoles(findResult.rid, ['moderator'], { fields: { u: 1 } }).fetch().map((sub) => sub.u); - return RocketChat.API.v1.success({ + return API.v1.success({ moderators, }); }, diff --git a/packages/rocketchat-api/server/v1/im.js b/packages/rocketchat-api/server/v1/im.js index b084dcbaa9ad..eb011021d119 100644 --- a/packages/rocketchat-api/server/v1/im.js +++ b/packages/rocketchat-api/server/v1/im.js @@ -1,5 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { RocketChat } from 'meteor/rocketchat:lib'; +import { Subscriptions, Uploads, Users, Messages, Rooms } from 'meteor/rocketchat:models'; +import { hasPermission } from 'meteor/rocketchat:authorization'; +import { composeMessageObjectWithUser } from 'meteor/rocketchat:utils'; +import { settings } from 'meteor/rocketchat:settings'; +import { API } from '../api'; function findDirectMessageRoom(params, user) { if ((!params.roomId || !params.roomId.trim()) && (!params.username || !params.username.trim())) { @@ -17,7 +22,7 @@ function findDirectMessageRoom(params, user) { throw new Meteor.Error('error-room-not-found', 'The required "roomId" or "username" param provided does not match any dirct message'); } - const subscription = RocketChat.models.Subscriptions.findOneByRoomIdAndUserId(room._id, user._id); + const subscription = Subscriptions.findOneByRoomIdAndUserId(room._id, user._id); return { room, @@ -25,35 +30,35 @@ function findDirectMessageRoom(params, user) { }; } -RocketChat.API.v1.addRoute(['dm.create', 'im.create'], { authRequired: true }, { +API.v1.addRoute(['dm.create', 'im.create'], { authRequired: true }, { post() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); - return RocketChat.API.v1.success({ + return API.v1.success({ room: findResult.room, }); }, }); -RocketChat.API.v1.addRoute(['dm.close', 'im.close'], { authRequired: true }, { +API.v1.addRoute(['dm.close', 'im.close'], { authRequired: true }, { post() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); if (!findResult.subscription.open) { - return RocketChat.API.v1.failure(`The direct message room, ${ this.bodyParams.name }, is already closed to the sender`); + return API.v1.failure(`The direct message room, ${ this.bodyParams.name }, is already closed to the sender`); } Meteor.runAsUser(this.userId, () => { Meteor.call('hideRoom', findResult.room._id); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute(['dm.counters', 'im.counters'], { authRequired: true }, { +API.v1.addRoute(['dm.counters', 'im.counters'], { authRequired: true }, { get() { - const access = RocketChat.authz.hasPermission(this.userId, 'view-room-administration'); + const access = hasPermission(this.userId, 'view-room-administration'); const ruserId = this.requestParams().userId; let user = this.userId; let unreads = null; @@ -67,7 +72,7 @@ RocketChat.API.v1.addRoute(['dm.counters', 'im.counters'], { authRequired: true if (ruserId) { if (!access) { - return RocketChat.API.v1.unauthorized(); + return API.v1.unauthorized(); } user = ruserId; } @@ -91,7 +96,7 @@ RocketChat.API.v1.addRoute(['dm.counters', 'im.counters'], { authRequired: true members = room.usersCount; } - return RocketChat.API.v1.success({ + return API.v1.success({ joined, members, unreads, @@ -103,7 +108,7 @@ RocketChat.API.v1.addRoute(['dm.counters', 'im.counters'], { authRequired: true }, }); -RocketChat.API.v1.addRoute(['dm.files', 'im.files'], { authRequired: true }, { +API.v1.addRoute(['dm.files', 'im.files'], { authRequired: true }, { get() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); const addUserObjectToEveryObject = (file) => { @@ -118,23 +123,23 @@ RocketChat.API.v1.addRoute(['dm.files', 'im.files'], { authRequired: true }, { const ourQuery = Object.assign({}, query, { rid: findResult.room._id }); - const files = RocketChat.models.Uploads.find(ourQuery, { + const files = Uploads.find(ourQuery, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ files: files.map(addUserObjectToEveryObject), count: files.length, offset, - total: RocketChat.models.Uploads.find(ourQuery).count(), + total: Uploads.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute(['dm.history', 'im.history'], { authRequired: true }, { +API.v1.addRoute(['dm.history', 'im.history'], { authRequired: true }, { get() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); @@ -170,20 +175,20 @@ RocketChat.API.v1.addRoute(['dm.history', 'im.history'], { authRequired: true }, }); if (!result) { - return RocketChat.API.v1.unauthorized(); + return API.v1.unauthorized(); } - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); -RocketChat.API.v1.addRoute(['dm.members', 'im.members'], { authRequired: true }, { +API.v1.addRoute(['dm.members', 'im.members'], { authRequired: true }, { get() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); const { offset, count } = this.getPaginationItems(); const { sort } = this.parseJsonQuery(); - const cursor = RocketChat.models.Subscriptions.findByRoomId(findResult.room._id, { + const cursor = Subscriptions.findByRoomId(findResult.room._id, { sort: { 'u.username': sort && sort.username ? sort.username : 1 }, skip: offset, limit: count, @@ -192,12 +197,12 @@ RocketChat.API.v1.addRoute(['dm.members', 'im.members'], { authRequired: true }, const total = cursor.count(); const members = cursor.fetch().map((s) => s.u && s.u.username); - const users = RocketChat.models.Users.find({ username: { $in: members } }, { + const users = Users.find({ username: { $in: members } }, { fields: { _id: 1, username: 1, name: 1, status: 1, utcOffset: 1 }, sort: { username: sort && sort.username ? sort.username : 1 }, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ members: users, count: members.length, offset, @@ -206,7 +211,7 @@ RocketChat.API.v1.addRoute(['dm.members', 'im.members'], { authRequired: true }, }, }); -RocketChat.API.v1.addRoute(['dm.messages', 'im.messages'], { authRequired: true }, { +API.v1.addRoute(['dm.messages', 'im.messages'], { authRequired: true }, { get() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); @@ -215,30 +220,30 @@ RocketChat.API.v1.addRoute(['dm.messages', 'im.messages'], { authRequired: true const ourQuery = Object.assign({}, query, { rid: findResult.room._id }); - const messages = RocketChat.models.Messages.find(ourQuery, { + const messages = Messages.find(ourQuery, { sort: sort ? sort : { ts: -1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ - messages: messages.map((message) => RocketChat.composeMessageObjectWithUser(message, this.userId)), + return API.v1.success({ + messages: messages.map((message) => composeMessageObjectWithUser(message, this.userId)), count: messages.length, offset, - total: RocketChat.models.Messages.find(ourQuery).count(), + total: Messages.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute(['dm.messages.others', 'im.messages.others'], { authRequired: true }, { +API.v1.addRoute(['dm.messages.others', 'im.messages.others'], { authRequired: true }, { get() { - if (RocketChat.settings.get('API_Enable_Direct_Message_History_EndPoint') !== true) { + if (settings.get('API_Enable_Direct_Message_History_EndPoint') !== true) { throw new Meteor.Error('error-endpoint-disabled', 'This endpoint is disabled', { route: '/api/v1/im.messages.others' }); } - if (!RocketChat.authz.hasPermission(this.userId, 'view-room-administration')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'view-room-administration')) { + return API.v1.unauthorized(); } const { roomId } = this.queryParams; @@ -246,7 +251,7 @@ RocketChat.API.v1.addRoute(['dm.messages.others', 'im.messages.others'], { authR throw new Meteor.Error('error-roomid-param-not-provided', 'The parameter "roomId" is required'); } - const room = RocketChat.models.Rooms.findOneById(roomId); + const room = Rooms.findOneById(roomId); if (!room || room.t !== 'd') { throw new Meteor.Error('error-room-not-found', `No direct message room found by the id of: ${ roomId }`); } @@ -255,30 +260,30 @@ RocketChat.API.v1.addRoute(['dm.messages.others', 'im.messages.others'], { authR const { sort, fields, query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query, { rid: room._id }); - const msgs = RocketChat.models.Messages.find(ourQuery, { + const msgs = Messages.find(ourQuery, { sort: sort ? sort : { ts: -1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ - messages: msgs.map((message) => RocketChat.composeMessageObjectWithUser(message, this.userId)), + return API.v1.success({ + messages: msgs.map((message) => composeMessageObjectWithUser(message, this.userId)), offset, count: msgs.length, - total: RocketChat.models.Messages.find(ourQuery).count(), + total: Messages.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute(['dm.list', 'im.list'], { authRequired: true }, { +API.v1.addRoute(['dm.list', 'im.list'], { authRequired: true }, { get() { const { offset, count } = this.getPaginationItems(); const { sort = { name: 1 }, fields } = this.parseJsonQuery(); // TODO: CACHE: Add Breacking notice since we removed the query param - const cursor = RocketChat.models.Rooms.findBySubscriptionTypeAndUserId('d', this.userId, { + const cursor = Rooms.findBySubscriptionTypeAndUserId('d', this.userId, { sort, skip: offset, limit: count, @@ -288,7 +293,7 @@ RocketChat.API.v1.addRoute(['dm.list', 'im.list'], { authRequired: true }, { const total = cursor.count(); const rooms = cursor.fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ ims: rooms.map((room) => this.composeRoomWithLastMessage(room, this.userId)), offset, count: rooms.length, @@ -297,10 +302,10 @@ RocketChat.API.v1.addRoute(['dm.list', 'im.list'], { authRequired: true }, { }, }); -RocketChat.API.v1.addRoute(['dm.list.everyone', 'im.list.everyone'], { authRequired: true }, { +API.v1.addRoute(['dm.list.everyone', 'im.list.everyone'], { authRequired: true }, { get() { - if (!RocketChat.authz.hasPermission(this.userId, 'view-room-administration')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'view-room-administration')) { + return API.v1.unauthorized(); } const { offset, count } = this.getPaginationItems(); @@ -308,23 +313,23 @@ RocketChat.API.v1.addRoute(['dm.list.everyone', 'im.list.everyone'], { authRequi const ourQuery = Object.assign({}, query, { t: 'd' }); - const rooms = RocketChat.models.Rooms.find(ourQuery, { + const rooms = Rooms.find(ourQuery, { sort: sort ? sort : { name: 1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ ims: rooms.map((room) => this.composeRoomWithLastMessage(room, this.userId)), offset, count: rooms.length, - total: RocketChat.models.Rooms.find(ourQuery).count(), + total: Rooms.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute(['dm.open', 'im.open'], { authRequired: true }, { +API.v1.addRoute(['dm.open', 'im.open'], { authRequired: true }, { post() { const findResult = findDirectMessageRoom(this.requestParams(), this.user); @@ -334,14 +339,14 @@ RocketChat.API.v1.addRoute(['dm.open', 'im.open'], { authRequired: true }, { }); } - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute(['dm.setTopic', 'im.setTopic'], { authRequired: true }, { +API.v1.addRoute(['dm.setTopic', 'im.setTopic'], { authRequired: true }, { post() { if (!this.bodyParams.topic || !this.bodyParams.topic.trim()) { - return RocketChat.API.v1.failure('The bodyParam "topic" is required'); + return API.v1.failure('The bodyParam "topic" is required'); } const findResult = findDirectMessageRoom(this.requestParams(), this.user); @@ -350,7 +355,7 @@ RocketChat.API.v1.addRoute(['dm.setTopic', 'im.setTopic'], { authRequired: true Meteor.call('saveRoomSettings', findResult.room._id, 'roomTopic', this.bodyParams.topic); }); - return RocketChat.API.v1.success({ + return API.v1.success({ topic: this.bodyParams.topic, }); }, diff --git a/packages/rocketchat-api/server/v1/import.js b/packages/rocketchat-api/server/v1/import.js index acd596e47e83..a68788a40a55 100644 --- a/packages/rocketchat-api/server/v1/import.js +++ b/packages/rocketchat-api/server/v1/import.js @@ -1,33 +1,33 @@ import { Meteor } from 'meteor/meteor'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { API } from '../api'; -RocketChat.API.v1.addRoute('uploadImportFile', { authRequired: true }, { +API.v1.addRoute('uploadImportFile', { authRequired: true }, { post() { const { binaryContent, contentType, fileName, importerKey } = this.bodyParams; Meteor.runAsUser(this.userId, () => { - RocketChat.API.v1.success(Meteor.call('uploadImportFile', binaryContent, contentType, fileName, importerKey)); + API.v1.success(Meteor.call('uploadImportFile', binaryContent, contentType, fileName, importerKey)); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('downloadPublicImportFile', { authRequired: true }, { +API.v1.addRoute('downloadPublicImportFile', { authRequired: true }, { post() { const { fileUrl, importerKey } = this.bodyParams; Meteor.runAsUser(this.userId, () => { - RocketChat.API.v1.success(Meteor.call('downloadPublicImportFile', fileUrl, importerKey)); + API.v1.success(Meteor.call('downloadPublicImportFile', fileUrl, importerKey)); }); - return RocketChat.API.v1.success(); + return API.v1.success(); }, }); -RocketChat.API.v1.addRoute('getImportFileData', { authRequired: true }, { +API.v1.addRoute('getImportFileData', { authRequired: true }, { get() { const { importerKey } = this.requestParams(); let result; @@ -35,16 +35,16 @@ RocketChat.API.v1.addRoute('getImportFileData', { authRequired: true }, { result = Meteor.call('getImportFileData', importerKey); }); - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); -RocketChat.API.v1.addRoute('getLatestImportOperations', { authRequired: true }, { +API.v1.addRoute('getLatestImportOperations', { authRequired: true }, { get() { let result; Meteor.runAsUser(this.userId, () => result = Meteor.call('getLatestImportOperations')); - return RocketChat.API.v1.success(result); + return API.v1.success(result); }, }); diff --git a/packages/rocketchat-api/server/v1/integrations.js b/packages/rocketchat-api/server/v1/integrations.js index 8b47074daa6a..49e6e0a2c974 100644 --- a/packages/rocketchat-api/server/v1/integrations.js +++ b/packages/rocketchat-api/server/v1/integrations.js @@ -1,8 +1,10 @@ import { Meteor } from 'meteor/meteor'; import { Match, check } from 'meteor/check'; -import { RocketChat } from 'meteor/rocketchat:lib'; +import { hasPermission } from 'meteor/rocketchat:authorization'; +import { IntegrationHistory, Integrations } from 'meteor/rocketchat:models'; +import { API } from '../api'; -RocketChat.API.v1.addRoute('integrations.create', { authRequired: true }, { +API.v1.addRoute('integrations.create', { authRequired: true }, { post() { check(this.bodyParams, Match.ObjectIncluding({ type: String, @@ -36,21 +38,21 @@ RocketChat.API.v1.addRoute('integrations.create', { authRequired: true }, { }); break; default: - return RocketChat.API.v1.failure('Invalid integration type.'); + return API.v1.failure('Invalid integration type.'); } - return RocketChat.API.v1.success({ integration }); + return API.v1.success({ integration }); }, }); -RocketChat.API.v1.addRoute('integrations.history', { authRequired: true }, { +API.v1.addRoute('integrations.history', { authRequired: true }, { get() { - if (!RocketChat.authz.hasPermission(this.userId, 'manage-integrations')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'manage-integrations')) { + return API.v1.unauthorized(); } if (!this.queryParams.id || this.queryParams.id.trim() === '') { - return RocketChat.API.v1.failure('Invalid integration id.'); + return API.v1.failure('Invalid integration id.'); } const { id } = this.queryParams; @@ -58,49 +60,49 @@ RocketChat.API.v1.addRoute('integrations.history', { authRequired: true }, { const { sort, fields, query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query, { 'integration._id': id }); - const history = RocketChat.models.IntegrationHistory.find(ourQuery, { + const history = IntegrationHistory.find(ourQuery, { sort: sort ? sort : { _updatedAt: -1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ history, offset, items: history.length, - total: RocketChat.models.IntegrationHistory.find(ourQuery).count(), + total: IntegrationHistory.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute('integrations.list', { authRequired: true }, { +API.v1.addRoute('integrations.list', { authRequired: true }, { get() { - if (!RocketChat.authz.hasPermission(this.userId, 'manage-integrations')) { - return RocketChat.API.v1.unauthorized(); + if (!hasPermission(this.userId, 'manage-integrations')) { + return API.v1.unauthorized(); } const { offset, count } = this.getPaginationItems(); const { sort, fields, query } = this.parseJsonQuery(); const ourQuery = Object.assign({}, query); - const integrations = RocketChat.models.Integrations.find(ourQuery, { + const integrations = Integrations.find(ourQuery, { sort: sort ? sort : { ts: -1 }, skip: offset, limit: count, fields, }).fetch(); - return RocketChat.API.v1.success({ + return API.v1.success({ integrations, offset, items: integrations.length, - total: RocketChat.models.Integrations.find(ourQuery).count(), + total: Integrations.find(ourQuery).count(), }); }, }); -RocketChat.API.v1.addRoute('integrations.remove', { authRequired: true }, { +API.v1.addRoute('integrations.remove', { authRequired: true }, { post() { check(this.bodyParams, Match.ObjectIncluding({ type: String, @@ -109,45 +111,45 @@ RocketChat.API.v1.addRoute('integrations.remove', { authRequired: true }, { })); if (!this.bodyParams.target_url && !this.bodyParams.integrationId) { - return RocketChat.API.v1.failure('An integrationId or target_url needs to be provided.'); + return API.v1.failure('An integrationId or target_url needs to be provided.'); } let integration; switch (this.bodyParams.type) { case 'webhook-outgoing': if (this.bodyParams.target_url) { - integration = RocketChat.models.Integrations.findOne({ urls: this.bodyParams.target_url }); + integration = Integrations.findOne({ urls: this.bodyParams.target_url }); } else if (this.bodyParams.integrationId) { - integration = RocketChat.models.Integrations.findOne({ _id: this.bodyParams.integrationId }); + integration = Integrations.findOne({ _id: this.bodyParams.integrationId }); } if (!integration) { - return RocketChat.API.v1.failure('No integration found.'); + return API.v1.failure('No integration found.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('deleteOutgoingIntegration', integration._id); }); - return RocketChat.API.v1.success({ + return API.v1.success({ integration, }); case 'webhook-incoming': - integration = RocketChat.models.Integrations.findOne({ _id: this.bodyParams.integrationId }); + integration = Integrations.findOne({ _id: this.bodyParams.integrationId }); if (!integration) { - return RocketChat.API.v1.failure('No integration found.'); + return API.v1.failure('No integration found.'); } Meteor.runAsUser(this.userId, () => { Meteor.call('deleteIncomingIntegration', integration._id); }); - return RocketChat.API.v1.success({ + return API.v1.success({ integration, }); default: - return RocketChat.API.v1.failure('Invalid integration type.'); + return API.v1.failure('Invalid integration type.'); } }, });