Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/modern-bikes-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@rocket.chat/rest-typings': minor
'@rocket.chat/meteor': minor
---

Migrated exisiting chat.ignore REST API to the new typed rest typed REst(openAPI) structure
5 changes: 5 additions & 0 deletions .changeset/spotty-spies-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': minor
---

Migrated chat.ignoreUser to typed endpoint
138 changes: 104 additions & 34 deletions apps/meteor/app/api/server/v1/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
isChatPostMessageProps,
isChatSearchProps,
isChatSendMessageProps,
isChatIgnoreUserProps,
isChatGetPinnedMessagesProps,
isChatGetMentionedMessagesProps,
isChatReactProps,
Expand Down Expand Up @@ -275,6 +274,67 @@ const isChatPinMessageProps = ajv.compile<ChatPinMessage>(ChatPinMessageSchema);

const isChatUnpinMessageProps = ajv.compile<ChatUnpinMessage>(ChatUnpinMessageSchema);

const isIgnoreUserResponse = ajv.compile<void>({
type: 'object',
properties: {
success: {
type: 'boolean',
enum: [true],
},
},
required: ['success'],
additionalProperties: false,
});

type ChatIgnoreUser = {
rid: string;
userId: string;
ignore: string;
};

const ChatIgnoreUserSchema = {
type: 'object',
properties: {
rid: {
type: 'string',
minLength: 1,
},
userId: {
type: 'string',
minLength: 1,
},
ignore: {
type: 'string',
minLength: 1,
},
},
required: ['rid', 'userId', 'ignore'],
additionalProperties: false,
};

const isChatIgnoreUserProps = ajv.compile<ChatIgnoreUser>(ChatIgnoreUserSchema);

const isChatPostMessageResponse = ajv.compile<{ ts: number; channel: string; message: IMessage }>({
type: 'object',
properties: {
ts: {
type: 'number',
},
channel: {
type: 'string',
},
message: {
$ref: '#/components/schemas/IMessage',
},
success: {
type: 'boolean',
enum: [true],
},
},
required: ['ts', 'channel', 'message', 'success'],
additionalProperties: false,
});

const chatEndpoints = API.v1
.post(
'chat.pinMessage',
Expand Down Expand Up @@ -558,13 +618,48 @@ const chatEndpoints = API.v1

return API.v1.success();
},
);
)
.get(
'chat.ignoreUser',
{
authRequired: true,
query: isChatIgnoreUserProps,
response: {
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
200: isIgnoreUserResponse,
},
},
async function action() {
const { rid, userId } = this.queryParams;
let { ignore = true } = this.queryParams;

API.v1.addRoute(
'chat.postMessage',
{ authRequired: true, validateParams: isChatPostMessageProps },
{
async post() {
ignore = typeof ignore === 'string' ? /true|1/.test(ignore) : ignore;
if (!rid?.trim()) {
throw new Meteor.Error('error-room-id-param-not-provided', 'The required "rid" param is missing.');
}

if (!userId?.trim()) {
throw new Meteor.Error('error-user-id-param-not-provided', 'The required "userId" param is missing.');
}

await ignoreUser(this.userId, { rid, userId, ignore });

return API.v1.success();
},
)
.post(
'chat.postMessage',
{
authRequired: true,
body: isChatPostMessageProps,
response: {
400: validateBadRequestErrorResponse,
401: validateUnauthorizedErrorResponse,
200: isChatPostMessageResponse,
},
},
async function action() {
const { text, attachments } = this.bodyParams;
const maxAllowedSize = settings.get<number>('Message_MaxAllowedSize') ?? 0;

Expand Down Expand Up @@ -594,8 +689,8 @@ API.v1.addRoute(
message,
});
},
},
);
);


API.v1.addRoute(
'chat.search',
Expand Down Expand Up @@ -698,31 +793,6 @@ API.v1.addRoute(
},
);

API.v1.addRoute(
'chat.ignoreUser',
{ authRequired: true, validateParams: isChatIgnoreUserProps },
{
async get() {
const { rid, userId } = this.queryParams;
let { ignore = true } = this.queryParams;

ignore = typeof ignore === 'string' ? /true|1/.test(ignore) : ignore;

if (!rid?.trim()) {
throw new Meteor.Error('error-room-id-param-not-provided', 'The required "rid" param is missing.');
}

if (!userId?.trim()) {
throw new Meteor.Error('error-user-id-param-not-provided', 'The required "userId" param is missing.');
}

await ignoreUser(this.userId, { rid, userId, ignore });

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

API.v1.addRoute(
'chat.getDeletedMessages',
{ authRequired: true, validateParams: isChatGetDeletedMessagesProps },
Expand Down
51 changes: 11 additions & 40 deletions packages/rest-typings/src/v1/chat.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IMessage, IRoom, MessageAttachment, IReadReceiptWithUser, MessageUrl, IThreadMainMessage } from '@rocket.chat/core-typings';

import { ajv } from './Ajv';
import { ajv, ajvQuery } from './Ajv';
import type { PaginatedRequest } from '../helpers/PaginatedRequest';

type ChatSendMessage = {
Expand Down Expand Up @@ -123,7 +123,7 @@ const ChatGetDiscussionsSchema = {
additionalProperties: false,
};

export const isChatGetDiscussionsProps = ajv.compile<ChatGetDiscussions>(ChatGetDiscussionsSchema);
export const isChatGetDiscussionsProps = ajvQuery.compile<ChatGetDiscussions>(ChatGetDiscussionsSchema);

type ChatReportMessage = {
messageId: IMessage['_id'];
Expand Down Expand Up @@ -193,7 +193,7 @@ const ChatGetThreadsListSchema = {
additionalProperties: false,
};

export const isChatGetThreadsListProps = ajv.compile<ChatGetThreadsList>(ChatGetThreadsListSchema);
export const isChatGetThreadsListProps = ajvQuery.compile<ChatGetThreadsList>(ChatGetThreadsListSchema);

type ChatSyncThreadsList = {
rid: IRoom['_id'];
Expand Down Expand Up @@ -295,33 +295,7 @@ export const isChatReactProps = ajv.compile<ChatReact>(ChatReactSchema);
* The param `ignore` cannot be boolean, since this is a GET method. Use strings 'true' or 'false' instead.
* @param {string} ignore
*/
type ChatIgnoreUser = {
rid: string;
userId: string;
ignore: string;
};

const ChatIgnoreUserSchema = {
type: 'object',
properties: {
rid: {
type: 'string',
minLength: 1,
},
userId: {
type: 'string',
minLength: 1,
},
ignore: {
type: 'string',
minLength: 1,
},
},
required: ['rid', 'userId', 'ignore'],
additionalProperties: false,
};

export const isChatIgnoreUserProps = ajv.compile<ChatIgnoreUser>(ChatIgnoreUserSchema);

type ChatSearch = PaginatedRequest<{
roomId: IRoom['_id'];
Expand Down Expand Up @@ -350,7 +324,7 @@ const ChatSearchSchema = {
additionalProperties: false,
};

export const isChatSearchProps = ajv.compile<ChatSearch>(ChatSearchSchema);
export const isChatSearchProps = ajvQuery.compile<ChatSearch>(ChatSearchSchema);

interface IChatUpdate {
roomId: IRoom['_id'];
Expand Down Expand Up @@ -527,7 +501,7 @@ const GetStarredMessagesSchema = {
additionalProperties: false,
};

export const isChatGetStarredMessagesProps = ajv.compile<GetStarredMessages>(GetStarredMessagesSchema);
export const isChatGetStarredMessagesProps = ajvQuery.compile<GetStarredMessages>(GetStarredMessagesSchema);

type GetPinnedMessages = {
roomId: IRoom['_id'];
Expand Down Expand Up @@ -560,7 +534,7 @@ const GetPinnedMessagesSchema = {
additionalProperties: false,
};

export const isChatGetPinnedMessagesProps = ajv.compile<GetPinnedMessages>(GetPinnedMessagesSchema);
export const isChatGetPinnedMessagesProps = ajvQuery.compile<GetPinnedMessages>(GetPinnedMessagesSchema);

type GetMentionedMessages = {
roomId: IRoom['_id'];
Expand Down Expand Up @@ -593,7 +567,7 @@ const GetMentionedMessagesSchema = {
additionalProperties: false,
};

export const isChatGetMentionedMessagesProps = ajv.compile<GetMentionedMessages>(GetMentionedMessagesSchema);
export const isChatGetMentionedMessagesProps = ajvQuery.compile<GetMentionedMessages>(GetMentionedMessagesSchema);

type ChatSyncMessages = {
roomId: IRoom['_id'];
Expand Down Expand Up @@ -636,7 +610,7 @@ const ChatSyncMessagesSchema = {
additionalProperties: false,
};

export const isChatSyncMessagesProps = ajv.compile<ChatSyncMessages>(ChatSyncMessagesSchema);
export const isChatSyncMessagesProps = ajvQuery.compile<ChatSyncMessages>(ChatSyncMessagesSchema);

type ChatSyncThreadMessages = PaginatedRequest<{
tmid: string;
Expand Down Expand Up @@ -671,7 +645,7 @@ const ChatSyncThreadMessagesSchema = {
additionalProperties: false,
};

export const isChatSyncThreadMessagesProps = ajv.compile<ChatSyncThreadMessages>(ChatSyncThreadMessagesSchema);
export const isChatSyncThreadMessagesProps = ajvQuery.compile<ChatSyncThreadMessages>(ChatSyncThreadMessagesSchema);

type ChatGetThreadMessages = PaginatedRequest<{
tmid: string;
Expand Down Expand Up @@ -701,7 +675,7 @@ const ChatGetThreadMessagesSchema = {
additionalProperties: false,
};

export const isChatGetThreadMessagesProps = ajv.compile<ChatGetThreadMessages>(ChatGetThreadMessagesSchema);
export const isChatGetThreadMessagesProps = ajvQuery.compile<ChatGetThreadMessages>(ChatGetThreadMessagesSchema);

type ChatGetDeletedMessages = PaginatedRequest<{
roomId: IRoom['_id'];
Expand Down Expand Up @@ -737,7 +711,7 @@ const ChatGetDeletedMessagesSchema = {
additionalProperties: false,
};

export const isChatGetDeletedMessagesProps = ajv.compile<ChatGetDeletedMessages>(ChatGetDeletedMessagesSchema);
export const isChatGetDeletedMessagesProps = ajvQuery.compile<ChatGetDeletedMessages>(ChatGetDeletedMessagesSchema);

type ChatPostMessage =
| {
Expand Down Expand Up @@ -930,9 +904,6 @@ export type ChatEndpoints = {
'/v1/chat.react': {
POST: (params: ChatReact) => void;
};
'/v1/chat.ignoreUser': {
GET: (params: ChatIgnoreUser) => void;
};
'/v1/chat.search': {
GET: (params: ChatSearch) => {
messages: IMessage[];
Expand Down