diff --git a/app/api/server/lib/messages.js b/app/api/server/lib/messages.js
index 257da349bb6e..fc33fba13a61 100644
--- a/app/api/server/lib/messages.js
+++ b/app/api/server/lib/messages.js
@@ -1,6 +1,7 @@
import { canAccessRoomAsync } from '../../../authorization/server/functions/canAccessRoom';
import { Rooms, Messages, Users } from '../../../models/server/raw';
import { getValue } from '../../../settings/server/raw';
+import { Message } from '../../../../server/sdk';
export async function findMentionedMessages({ uid, roomId, pagination: { offset, count, sort } }) {
const room = await Rooms.findOneById(roomId);
@@ -12,16 +13,16 @@ export async function findMentionedMessages({ uid, roomId, pagination: { offset,
throw new Error('invalid-user');
}
- const cursor = await Messages.findVisibleByMentionAndRoomId(user.username, roomId, {
- sort: sort || { ts: -1 },
- skip: offset,
- limit: count,
+ const { records: messages, total } = await Message.get(uid, {
+ rid: roomId,
+ mentionsUsername: user.username,
+ queryOptions: {
+ sort: sort || { ts: -1 },
+ skip: offset,
+ limit: count,
+ },
});
- const total = await cursor.count();
-
- const messages = await cursor.toArray();
-
return {
messages,
count: messages.length,
@@ -98,15 +99,13 @@ export async function findSnippetedMessages({ uid, roomId, pagination: { offset,
throw new Error('error-not-allowed');
}
- const cursor = await Messages.findSnippetedByRoom(roomId, {
+ const queryOptions = {
sort: sort || { ts: -1 },
skip: offset,
limit: count,
- });
-
- const total = await cursor.count();
+ };
- const messages = await cursor.toArray();
+ const { records: messages, total } = await Message.get(uid, { snippeted: true, queryOptions });
return {
messages,
@@ -123,16 +122,16 @@ export async function findDiscussionsFromRoom({ uid, roomId, text, pagination: {
throw new Error('error-not-allowed');
}
- const cursor = Messages.findDiscussionsByRoomAndText(roomId, text, {
- sort: sort || { ts: -1 },
- skip: offset,
- limit: count,
+ const { records: messages, total } = await Message.getDiscussions({
+ rid: roomId,
+ text,
+ queryOptions: {
+ sort: sort || { ts: -1 },
+ skip: offset,
+ limit: count,
+ },
});
- const total = await cursor.count();
-
- const messages = await cursor.toArray();
-
return {
messages,
count: messages.length,
diff --git a/app/api/server/v1/channels.js b/app/api/server/v1/channels.js
index 76af348d9a6c..4ac353773690 100644
--- a/app/api/server/v1/channels.js
+++ b/app/api/server/v1/channels.js
@@ -7,6 +7,7 @@ import { mountIntegrationQueryBasedOnPermissions } from '../../../integrations/s
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
import { API } from '../api';
import { settings } from '../../../settings';
+import { Message } from '../../../../server/sdk';
// Returns the channel IF found otherwise it will return the failure of why it didn't. Check the `statusCode` property
@@ -337,12 +338,12 @@ API.v1.addRoute('channels.history', { authRequired: true }, {
get() {
const findResult = findChannelByIdOrName({ params: this.requestParams(), checkedArchived: false });
- let latestDate = new Date();
+ let latestDate;
if (this.queryParams.latest) {
latestDate = new Date(this.queryParams.latest);
}
- let oldestDate = undefined;
+ let oldestDate;
if (this.queryParams.oldest) {
oldestDate = new Date(this.queryParams.oldest);
}
@@ -576,15 +577,16 @@ API.v1.addRoute('channels.messages', { authRequired: true }, {
return API.v1.unauthorized();
}
- const cursor = Messages.find(ourQuery, {
- sort: sort || { ts: -1 },
- skip: offset,
- limit: count,
- fields,
- });
-
- const total = cursor.count();
- const messages = cursor.fetch();
+ const { records: messages, total } = Promise.await(Message.customQuery({
+ query: ourQuery,
+ userId: this.userId,
+ queryOptions: {
+ sort: sort || { ts: -1 },
+ skip: offset,
+ limit: count,
+ fields,
+ },
+ }));
return API.v1.success({
messages: normalizeMessagesForUser(messages, this.userId),
diff --git a/app/api/server/v1/chat.js b/app/api/server/v1/chat.js
index a4ed9765ebe4..52bb679846ef 100644
--- a/app/api/server/v1/chat.js
+++ b/app/api/server/v1/chat.js
@@ -2,6 +2,7 @@ import { Meteor } from 'meteor/meteor';
import { Match, check } from 'meteor/check';
import { Messages } from '../../../models';
+import { Message } from '../../../../server/sdk';
import { canAccessRoom, hasPermission } from '../../../authorization';
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
import { processWebhookMessage } from '../../../lib/server';
@@ -408,14 +409,14 @@ API.v1.addRoute('chat.getPinnedMessages', { authRequired: true }, {
throw new Meteor.Error('error-not-allowed', 'Not allowed');
}
- const cursor = Messages.findPinnedByRoom(room._id, {
- skip: offset,
- limit: count,
- });
-
- const total = cursor.count();
-
- const messages = cursor.fetch();
+ const { records: messages, total } = Promise.await(Message.get(this.userId, {
+ rid: room._id,
+ pinned: true,
+ queryOptions: {
+ skip: offset,
+ limit: count,
+ },
+ }));
return API.v1.success({
messages,
@@ -456,16 +457,17 @@ API.v1.addRoute('chat.getThreadsList', { authRequired: true }, {
};
const threadQuery = { ...query, ...typeThread, rid, tcount: { $exists: true } };
- const cursor = Messages.find(threadQuery, {
- sort: sort || { tlm: -1 },
- skip: offset,
- limit: count,
- fields,
- });
-
- const total = cursor.count();
- const threads = cursor.fetch();
+ const { records: threads, total } = Promise.await(Message.customQuery({
+ query: threadQuery,
+ userId: this.userId,
+ queryOptions: {
+ sort: sort || { tlm: -1 },
+ skip: offset,
+ limit: count,
+ fields,
+ },
+ }));
return API.v1.success({
threads,
@@ -501,11 +503,12 @@ API.v1.addRoute('chat.syncThreadsList', { authRequired: true }, {
if (!canAccessRoom(room, user)) {
throw new Meteor.Error('error-not-allowed', 'Not Allowed');
}
- const threadQuery = Object.assign({}, query, { rid, tcount: { $exists: true } });
+ const threadQuery = { ...query, rid, tcount: { $exists: true } };
+
return API.v1.success({
threads: {
- update: Messages.find({ ...threadQuery, _updatedAt: { $gt: updatedSinceDate } }, { fields, sort }).fetch(),
- remove: Messages.trashFindDeletedAfter(updatedSinceDate, threadQuery, { fields, sort }).fetch(),
+ update: Promise.await(Message.customQuery({ query: { ...threadQuery, _updatedAt: { $gt: updatedSinceDate } }, queryOptions: { returnTotal: false, fields, sort } })).records,
+ remove: Promise.await(Message.getDeleted({ rid, userId: this.userId, timestamp: updatedSinceDate, query: threadQuery, queryOptions: { returnTotal: false, fields, sort } })).records,
},
});
},
@@ -533,16 +536,19 @@ API.v1.addRoute('chat.getThreadMessages', { authRequired: true }, {
if (!canAccessRoom(room, user)) {
throw new Meteor.Error('error-not-allowed', 'Not Allowed');
}
- const cursor = Messages.find({ ...query, tmid }, {
- sort: sort || { ts: 1 },
- skip: offset,
- limit: count,
- fields,
- });
- const total = cursor.count();
+ const ourQuery = Object.assign({}, query, { rid: thread.rid, tmid });
- const messages = cursor.fetch();
+ const { records: messages, total } = Promise.await(Message.customQuery({
+ query: ourQuery,
+ userId: this.userId,
+ queryOptions: {
+ sort: sort || { ts: 1 },
+ skip: offset,
+ limit: count,
+ fields,
+ },
+ }));
return API.v1.success({
messages,
@@ -573,6 +579,7 @@ API.v1.addRoute('chat.syncThreadMessages', { authRequired: true }, {
} else {
updatedSinceDate = new Date(updatedSince);
}
+
const thread = Messages.findOneById(tmid, { fields: { rid: 1 } });
if (!thread || !thread.rid) {
throw new Meteor.Error('error-invalid-message', 'Invalid Message');
@@ -583,10 +590,11 @@ API.v1.addRoute('chat.syncThreadMessages', { authRequired: true }, {
if (!canAccessRoom(room, user)) {
throw new Meteor.Error('error-not-allowed', 'Not Allowed');
}
+
return API.v1.success({
messages: {
- update: Messages.find({ ...query, tmid, _updatedAt: { $gt: updatedSinceDate } }, { fields, sort }).fetch(),
- remove: Messages.trashFindDeletedAfter(updatedSinceDate, { ...query, tmid }, { fields, sort }).fetch(),
+ update: Promise.await(Message.customQuery({ query: { ...query, tmid, _updatedAt: { $gt: updatedSinceDate } }, queryOptions: { returnTotal: false, fields, sort } })).records,
+ remove: Promise.await(Message.getDeleted({ rid: thread.rid, timestamp: updatedSinceDate, query: { ...query, tmid }, queryOptions: { returnTotal: false, fields, sort } })).records,
},
});
},
diff --git a/app/api/server/v1/groups.js b/app/api/server/v1/groups.js
index ba5002f8bbb4..9d2c4e5a8f92 100644
--- a/app/api/server/v1/groups.js
+++ b/app/api/server/v1/groups.js
@@ -7,6 +7,7 @@ import { Subscriptions, Rooms, Messages, Uploads, Integrations, Users } from '..
import { hasPermission, hasAtLeastOnePermission, canAccessRoom } from '../../../authorization/server';
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
import { API } from '../api';
+import { Message } from '../../../../server/sdk';
// Returns the private group subscription IF found otherwise it will return the failure of why it didn't. Check the `statusCode` property
export function findPrivateGroupByIdOrName({ params, userId, checkedArchived = true }) {
@@ -525,18 +526,22 @@ API.v1.addRoute('groups.messages', { authRequired: true }, {
const ourQuery = Object.assign({}, query, { rid: findResult.rid });
- const messages = Messages.find(ourQuery, {
- sort: sort || { ts: -1 },
- skip: offset,
- limit: count,
- fields,
- }).fetch();
+ const { records: messages, total } = Promise.await(Message.customQuery({
+ query: ourQuery,
+ userId: this.userId,
+ queryOptions: {
+ sort: sort || { ts: -1 },
+ skip: offset,
+ limit: count,
+ fields,
+ },
+ }));
return API.v1.success({
messages: normalizeMessagesForUser(messages, this.userId),
count: messages.length,
offset,
- total: Messages.find(ourQuery).count(),
+ total,
});
},
});
diff --git a/app/api/server/v1/im.js b/app/api/server/v1/im.js
index f61426949b08..a1c18b2023bc 100644
--- a/app/api/server/v1/im.js
+++ b/app/api/server/v1/im.js
@@ -1,11 +1,12 @@
import { Meteor } from 'meteor/meteor';
-import { Subscriptions, Uploads, Users, Messages, Rooms } from '../../../models';
+import { Subscriptions, Uploads, Users, Rooms } from '../../../models';
import { hasPermission } from '../../../authorization';
import { normalizeMessagesForUser } from '../../../utils/server/lib/normalizeMessagesForUser';
import { settings } from '../../../settings';
import { API } from '../api';
import { getDirectMessageByNameOrIdWithOptionToJoin } from '../../../lib/server/functions/getDirectMessageByNameOrIdWithOptionToJoin';
+import { Message } from '../../../../server/sdk';
function findDirectMessageRoom(params, user) {
if ((!params.roomId || !params.roomId.trim()) && (!params.username || !params.username.trim())) {
@@ -234,18 +235,22 @@ API.v1.addRoute(['dm.messages', 'im.messages'], { authRequired: true }, {
const ourQuery = Object.assign({}, query, { rid: findResult.room._id });
- const messages = Messages.find(ourQuery, {
- sort: sort || { ts: -1 },
- skip: offset,
- limit: count,
- fields,
- }).fetch();
+ const { records: messages, total } = Promise.await(Message.customQuery({
+ query: ourQuery,
+ userId: this.userId,
+ queryOptions: {
+ sort: sort || { ts: -1 },
+ skip: offset,
+ limit: count,
+ fields,
+ },
+ }));
return API.v1.success({
messages: normalizeMessagesForUser(messages, this.userId),
count: messages.length,
offset,
- total: Messages.find(ourQuery).count(),
+ total,
});
},
});
@@ -274,18 +279,22 @@ API.v1.addRoute(['dm.messages.others', 'im.messages.others'], { authRequired: tr
const { sort, fields, query } = this.parseJsonQuery();
const ourQuery = Object.assign({}, query, { rid: room._id });
- const msgs = Messages.find(ourQuery, {
- sort: sort || { ts: -1 },
- skip: offset,
- limit: count,
- fields,
- }).fetch();
+ const { records: msgs, total } = Promise.await(Message.customQuery({
+ query: ourQuery,
+ userId: this.userId,
+ queryOptions: {
+ sort: sort || { ts: -1 },
+ skip: offset,
+ limit: count,
+ fields,
+ },
+ }));
return API.v1.success({
messages: normalizeMessagesForUser(msgs, this.userId),
offset,
count: msgs.length,
- total: Messages.find(ourQuery).count(),
+ total,
});
},
});
diff --git a/app/channel-settings/server/methods/saveRoomSettings.js b/app/channel-settings/server/methods/saveRoomSettings.js
index e524637e8b96..c89a99aaba5d 100644
--- a/app/channel-settings/server/methods/saveRoomSettings.js
+++ b/app/channel-settings/server/methods/saveRoomSettings.js
@@ -18,8 +18,9 @@ import { saveRoomTokenpass } from '../functions/saveRoomTokens';
import { saveRoomEncrypted } from '../functions/saveRoomEncrypted';
import { saveStreamingOptions } from '../functions/saveStreamingOptions';
import { RoomSettingsEnum, roomTypes } from '../../../utils';
+import { isEnterprise } from '../../../../ee/app/license/server/license';
-const fields = ['roomAvatar', 'featured', 'roomName', 'roomTopic', 'roomAnnouncement', 'roomCustomFields', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode', 'tokenpass', 'streamingOptions', 'retentionEnabled', 'retentionMaxAge', 'retentionExcludePinned', 'retentionFilesOnly', 'retentionIgnoreThreads', 'retentionOverrideGlobal', 'encrypted', 'favorite'];
+const fields = ['roomAvatar', 'featured', 'roomName', 'roomTopic', 'roomAnnouncement', 'roomCustomFields', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode', 'tokenpass', 'streamingOptions', 'retentionEnabled', 'retentionMaxAge', 'retentionExcludePinned', 'retentionFilesOnly', 'retentionIgnoreThreads', 'retentionOverrideGlobal', 'encrypted', 'favorite', 'hideHistoryForNewMembers'];
const validators = {
default({ userId }) {
@@ -122,6 +123,14 @@ const validators = {
});
}
},
+ hideHistoryForNewMembers({ value }) {
+ if (!isEnterprise() && value) {
+ throw new Meteor.Error('error-action-not-allowed', 'Hiding the history for new users is not allowed.', {
+ method: 'saveRoomSettings',
+ action: 'Editing_room',
+ });
+ }
+ },
};
const settingSavers = {
@@ -217,6 +226,9 @@ const settingSavers = {
roomAvatar({ value, rid, user }) {
setRoomAvatar(rid, value, user);
},
+ hideHistoryForNewMembers({ value, rid }) {
+ Rooms.saveHideHistoryForNewMembers(rid, value);
+ },
};
Meteor.methods({
diff --git a/app/discussion/client/views/creationDialog/CreateDiscussion.html b/app/discussion/client/views/creationDialog/CreateDiscussion.html
index 9eff9c8e57ad..fe0cda2f1dd1 100644
--- a/app/discussion/client/views/creationDialog/CreateDiscussion.html
+++ b/app/discussion/client/views/creationDialog/CreateDiscussion.html
@@ -43,6 +43,22 @@
+ {{#if hideHistoryVisible}}
+
+
+
+ {{hideHistoryDescription}}
+
+
+ {{/if}}
{{/if}}
+ {{#if hideHistoryVisible}}
+
+
+
+ {{hideHistoryDescription}}
+
+
+ {{/if}}
+