Skip to content

Commit

Permalink
Merge branch 'feat/federation-feat-2' into fix/federation-users-admin
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcosSpessatto committed Feb 13, 2023
2 parents f9b42de + 6027839 commit 3a6a733
Show file tree
Hide file tree
Showing 490 changed files with 6,387 additions and 5,690 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/build_and_test.yml
Expand Up @@ -454,9 +454,6 @@ jobs:
- name: yarn build
run: yarn build

- name: Unit Test
run: yarn testunit --api="http://127.0.0.1:9080" --token="${{ secrets.TURBO_SERVER_TOKEN }}" --team='rc'

- name: Restore build
uses: actions/download-artifact@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Expand Up @@ -14,5 +14,5 @@
}
],
"typescript.tsdk": "./node_modules/typescript/lib",
"cSpell.words": ["katex", "livechat", "omnichannel", "photoswipe", "tmid"]
"cSpell.words": ["katex", "listbox", "livechat", "omnichannel", "photoswipe", "searchbox", "tmid"]
}
1 change: 0 additions & 1 deletion apps/meteor/.meteor/packages
Expand Up @@ -45,7 +45,6 @@ rocketchat:livechat
rocketchat:streamer
rocketchat:version

konecty:multiple-instances-status
konecty:user-presence

dispatch:run-as-user
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/.meteor/versions
Expand Up @@ -60,7 +60,6 @@ jparker:crypto-md5@0.1.1
jparker:gravatar@0.5.1
jquery@3.0.0
kadira:flow-router@2.12.1
konecty:multiple-instances-status@1.1.0
konecty:user-presence@2.6.3
launch-screen@1.3.0
littledata:synced-cron@1.5.1
Expand Down
2 changes: 2 additions & 0 deletions apps/meteor/.mocharc.client.js
Expand Up @@ -28,6 +28,8 @@ module.exports = {
'./tests/setup/hoistedReact.ts',
'./tests/setup/cleanupTestingLibrary.ts',
],
reporter: 'dot',
timeout: 5000,
exit: false,
slow: 200,
spec: [
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/app/api/server/index.ts
Expand Up @@ -27,6 +27,7 @@ import './v1/import';
import './v1/ldap';
import './v1/misc';
import './v1/permissions';
import './v1/presence';
import './v1/push';
import './v1/roles';
import './v1/rooms.js';
Expand Down
68 changes: 0 additions & 68 deletions apps/meteor/app/api/server/lib/messages.ts
Expand Up @@ -3,7 +3,6 @@ import type { IMessage, IUser } from '@rocket.chat/core-typings';
import { Rooms, Messages, Users } from '@rocket.chat/models';

import { canAccessRoomAsync } from '../../../authorization/server/functions/canAccessRoom';
import { getValue } from '../../../settings/server/raw';

export async function findMentionedMessages({
uid,
Expand Down Expand Up @@ -83,73 +82,6 @@ export async function findStarredMessages({
};
}

export async function findSnippetedMessageById({ uid, messageId }: { uid: string; messageId: string }): Promise<IMessage> {
if (!(await getValue('Message_AllowSnippeting'))) {
throw new Error('error-not-allowed');
}

if (!uid) {
throw new Error('invalid-user');
}

const snippet = await Messages.findOne({ _id: messageId, snippeted: true });

if (!snippet) {
throw new Error('invalid-message');
}

const room = await Rooms.findOneById(snippet.rid);

if (!room) {
throw new Error('invalid-message');
}

if (!(await canAccessRoomAsync(room, { _id: uid }))) {
throw new Error('error-not-allowed');
}

return snippet;
}

export async function findSnippetedMessages({
uid,
roomId,
pagination: { offset, count, sort },
}: {
uid: string;
roomId: string;
pagination: { offset: number; count: number; sort: FindOptions<IMessage>['sort'] };
}): Promise<{
messages: IMessage[];
count: number;
offset: number;
total: number;
}> {
if (!(await getValue('Message_AllowSnippeting'))) {
throw new Error('error-not-allowed');
}
const room = await Rooms.findOneById(roomId);

if (!room || !(await canAccessRoomAsync(room, { _id: uid }))) {
throw new Error('error-not-allowed');
}

const { cursor, totalCount } = Messages.findSnippetedByRoom(roomId, {
sort: sort || { ts: -1 },
skip: offset,
limit: count,
});

const [messages, total] = await Promise.all([cursor.toArray(), totalCount]);

return {
messages,
count: messages.length,
offset,
total,
};
}

export async function findDiscussionsFromRoom({
uid,
roomId,
Expand Down
57 changes: 1 addition & 56 deletions apps/meteor/app/api/server/v1/chat.js
Expand Up @@ -14,13 +14,7 @@ import Rooms from '../../../models/server/models/Rooms';
import Users from '../../../models/server/models/Users';
import Subscriptions from '../../../models/server/models/Subscriptions';
import { settings } from '../../../settings/server';
import {
findMentionedMessages,
findStarredMessages,
findSnippetedMessageById,
findSnippetedMessages,
findDiscussionsFromRoom,
} from '../lib/messages';
import { findMentionedMessages, findStarredMessages, findDiscussionsFromRoom } from '../lib/messages';

API.v1.addRoute(
'chat.delete',
Expand Down Expand Up @@ -786,55 +780,6 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'chat.getSnippetedMessageById',
{ authRequired: true },
{
get() {
const { messageId } = this.queryParams;

if (!messageId) {
throw new Meteor.Error('error-invalid-params', 'The required "messageId" query param is missing.');
}
const message = Promise.await(
findSnippetedMessageById({
uid: this.userId,
messageId,
}),
);
return API.v1.success(message);
},
},
);

API.v1.addRoute(
'chat.getSnippetedMessages',
{ authRequired: true },
{
get() {
const { roomId } = this.queryParams;
const { sort } = this.parseJsonQuery();
const { offset, count } = this.getPaginationItems();

if (!roomId) {
throw new Meteor.Error('error-invalid-params', 'The required "roomId" query param is missing.');
}
const messages = Promise.await(
findSnippetedMessages({
uid: this.userId,
roomId,
pagination: {
offset,
count,
sort,
},
}),
);
return API.v1.success(messages);
},
},
);

API.v1.addRoute(
'chat.getDiscussions',
{ authRequired: true },
Expand Down
26 changes: 25 additions & 1 deletion apps/meteor/app/api/server/v1/invites.ts
@@ -1,13 +1,19 @@
/* eslint-disable react-hooks/rules-of-hooks */
import type { IInvite } from '@rocket.chat/core-typings';
import { isFindOrCreateInviteParams, isUseInviteTokenProps, isValidateInviteTokenProps } from '@rocket.chat/rest-typings';
import {
isFindOrCreateInviteParams,
isUseInviteTokenProps,
isValidateInviteTokenProps,
isSendInvitationEmailParams,
} from '@rocket.chat/rest-typings';

import { API } from '../api';
import { findOrCreateInvite } from '../../../invites/server/functions/findOrCreateInvite';
import { removeInvite } from '../../../invites/server/functions/removeInvite';
import { listInvites } from '../../../invites/server/functions/listInvites';
import { useInviteToken } from '../../../invites/server/functions/useInviteToken';
import { validateInviteToken } from '../../../invites/server/functions/validateInviteToken';
import { sendInvitationEmail } from '../../../invites/server/functions/sendInvitationEmail';

API.v1.addRoute(
'listInvites',
Expand Down Expand Up @@ -82,3 +88,21 @@ API.v1.addRoute(
},
},
);

API.v1.addRoute(
'sendInvitationEmail',
{
authRequired: true,
validateParams: isSendInvitationEmailParams,
},
{
async post() {
const { emails } = this.bodyParams;
try {
return API.v1.success({ success: Boolean(await sendInvitationEmail(this.userId, emails)) });
} catch (e: any) {
return API.v1.failure({ error: e.message });
}
},
},
);
27 changes: 27 additions & 0 deletions apps/meteor/app/api/server/v1/presence.ts
@@ -0,0 +1,27 @@
import { Presence } from '@rocket.chat/core-services';

import { API } from '../api';

API.v1.addRoute(
'presence.getConnections',
{ authRequired: true, permissionsRequired: ['manage-user-status'] },
{
async get() {
const result = await Presence.getConnectionCount();

return API.v1.success(result);
},
},
);

API.v1.addRoute(
'presence.enableBroadcast',
{ authRequired: true, permissionsRequired: ['manage-user-status'], twoFactorRequired: true },
{
async post() {
await Presence.toggleBroadcast(true);

return API.v1.success();
},
},
);
88 changes: 1 addition & 87 deletions apps/meteor/app/api/server/v1/roles.ts
@@ -1,12 +1,6 @@
import { Meteor } from 'meteor/meteor';
import { check, Match } from 'meteor/check';
import {
isRoleAddUserToRoleProps,
isRoleCreateProps,
isRoleDeleteProps,
isRoleRemoveUserFromRoleProps,
isRoleUpdateProps,
} from '@rocket.chat/rest-typings';
import { isRoleAddUserToRoleProps, isRoleDeleteProps, isRoleRemoveUserFromRoleProps } from '@rocket.chat/rest-typings';
import type { IRole } from '@rocket.chat/core-typings';
import { Roles } from '@rocket.chat/models';
import { api } from '@rocket.chat/core-services';
Expand All @@ -19,8 +13,6 @@ import { settings } from '../../../settings/server/index';
import { apiDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { hasAnyRoleAsync } from '../../../authorization/server/functions/hasRole';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { updateRole } from '../../../../server/lib/roles/updateRole';
import { insertRole } from '../../../../server/lib/roles/insertRole';

API.v1.addRoute(
'roles.list',
Expand Down Expand Up @@ -58,48 +50,6 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'roles.create',
{ authRequired: true },
{
async post() {
if (!isRoleCreateProps(this.bodyParams)) {
throw new Meteor.Error('error-invalid-role-properties', 'The role properties are invalid.');
}

const userId = Meteor.userId();

if (!userId || !(await hasPermissionAsync(userId, 'access-permissions'))) {
throw new Meteor.Error('error-action-not-allowed', 'Accessing permissions is not allowed');
}

const { name, scope, description, mandatory2fa } = this.bodyParams;

if (await Roles.findOneByIdOrName(name)) {
throw new Meteor.Error('error-duplicate-role-names-not-allowed', 'Role name already exists');
}

const roleData = {
description: description || '',
...(mandatory2fa !== undefined && { mandatory2fa }),
name,
scope: scope || 'Users',
protected: false,
};

const options = {
broadcastUpdate: settings.get<boolean>('UI_DisplayRoles'),
};

const role = insertRole(roleData, options);

return API.v1.success({
role,
});
},
},
);

API.v1.addRoute(
'roles.addUserToRole',
{ authRequired: true },
Expand Down Expand Up @@ -190,42 +140,6 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'roles.update',
{ authRequired: true },
{
async post() {
if (!isRoleUpdateProps(this.bodyParams)) {
throw new Meteor.Error('error-invalid-role-properties', 'The role properties are invalid.');
}

if (!(await hasPermissionAsync(this.userId, 'access-permissions'))) {
throw new Meteor.Error('error-action-not-allowed', 'Accessing permissions is not allowed');
}

const { roleId, name, scope, description, mandatory2fa } = this.bodyParams;

const roleData = {
description: description || '',
...(mandatory2fa !== undefined && { mandatory2fa }),
name,
scope: scope || 'Users',
protected: false,
};

const options = {
broadcastUpdate: settings.get<boolean>('UI_DisplayRoles'),
};

const role = updateRole(roleId, roleData, options);

return API.v1.success({
role,
});
},
},
);

API.v1.addRoute(
'roles.delete',
{ authRequired: true },
Expand Down

0 comments on commit 3a6a733

Please sign in to comment.