Skip to content

Commit

Permalink
chore!: make channels files list stop to use query param (#33564)
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardogarim authored and ggazzo committed Oct 17, 2024
1 parent c1d2765 commit 4b64cf7
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 13 deletions.
3 changes: 2 additions & 1 deletion apps/meteor/app/api/server/helpers/parseJsonQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ export async function parseJsonQuery(api: PartialThis): Promise<{
}

// TODO: Remove this once we have all routes migrated to the new API params
const hasSupportedRoutes = ['/api/v1/integrations.list', '/api/v1/custom-user-status.list'].includes(route);
const hasSupportedRoutes = ['/api/v1/channels.files', '/api/v1/integrations.list', '/api/v1/custom-user-status.list'].includes(route);

const isUnsafeQueryParamsAllowed = process.env.ALLOW_UNSAFE_QUERY_AND_FIELDS_API_PARAMS?.toUpperCase() === 'TRUE';
const messageGenerator = ({ endpoint, version, parameter }: { endpoint: string; version: string; parameter: string }): string =>
`The usage of the "${parameter}" parameter in endpoint "${endpoint}" breaks the security of the API and can lead to data exposure. It has been deprecated and will be removed in the version ${version}.`;
Expand Down
19 changes: 15 additions & 4 deletions apps/meteor/app/api/server/v1/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
isChannelsConvertToTeamProps,
isChannelsSetReadOnlyProps,
isChannelsDeleteProps,
isChannelsFilesListProps,
} from '@rocket.chat/rest-typings';
import { Meteor } from 'meteor/meteor';

Expand Down Expand Up @@ -763,11 +764,16 @@ API.v1.addRoute(

API.v1.addRoute(
'channels.files',
{ authRequired: true },
{ authRequired: true, validateParams: isChannelsFilesListProps },
{
async get() {
const { typeGroup, name, roomId, roomName } = this.queryParams;

const findResult = await findChannelByIdOrName({
params: this.queryParams,
params: {
...(roomId ? { roomId } : {}),
...(roomName ? { roomName } : {}),
},
checkedArchived: false,
});

Expand All @@ -778,9 +784,14 @@ API.v1.addRoute(
const { offset, count } = await getPaginationItems(this.queryParams);
const { sort, fields, query } = await this.parseJsonQuery();

const ourQuery = Object.assign({}, query, { rid: findResult._id });
const filter = {
rid: findResult._id,
...query,
...(name ? { name: { $regex: name || '', $options: 'i' } } : {}),
...(typeGroup ? { typeGroup } : {}),
};

const { cursor, totalCount } = await Uploads.findPaginatedWithoutThumbs(ourQuery, {
const { cursor, totalCount } = await Uploads.findPaginatedWithoutThumbs(filter, {
sort: sort || { name: 1 },
skip: offset,
limit: count,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,9 @@ export const useFilesList = (
offset: start,
count: end,
sort: JSON.stringify({ uploadedAt: -1 }),
query: JSON.stringify({
name: { $regex: options.text || '', $options: 'i' },
...(options.type !== 'all' && {
typeGroup: options.type,
}),
...(options.text ? { name: options.text } : {}),
...(options.type !== 'all' && {
typeGroup: options.type,
}),
});

Expand Down
58 changes: 58 additions & 0 deletions packages/rest-typings/src/v1/channels/ChannelsFilesListProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Ajv from 'ajv';

import type { PaginatedRequest } from '../../helpers/PaginatedRequest';

const ajv = new Ajv({
coerceTypes: true,
});

export type ChannelsFilesListProps = PaginatedRequest<
({ roomId: string; roomName?: string } | { roomId?: string; roomName: string }) & {
name?: string;
typeGroup?: string;
query?: string;
}
>;

const channelsFilesListPropsSchema = {
type: 'object',
properties: {
roomId: {
type: 'string',
nullable: true,
},
roomName: {
type: 'string',
nullable: true,
},
offset: {
type: 'number',
nullable: true,
},
count: {
type: 'number',
nullable: true,
},
sort: {
type: 'string',
nullable: true,
},
name: {
type: 'string',
nullable: true,
},
typeGroup: {
type: 'string',
nullable: true,
},
query: {
type: 'string',
nullable: true,
},
},
oneOf: [{ required: ['roomId'] }, { required: ['roomName'] }],
required: [],
additionalProperties: false,
};

export const isChannelsFilesListProps = ajv.compile<ChannelsFilesListProps>(channelsFilesListPropsSchema);
16 changes: 14 additions & 2 deletions packages/rest-typings/src/v1/channels/ChannelsListProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ const ajv = new Ajv({
coerceTypes: true,
});

export type ChannelsListProps = PaginatedRequest<null>;
const channelsListPropsSchema = {};
export type ChannelsListProps = PaginatedRequest<{ query?: string }>;

const channelsListPropsSchema = {
type: 'object',
properties: {
query: {
type: 'string',
nullable: true,
},
},
required: [],
additionalProperties: false,
};

export const isChannelsListProps = ajv.compile<ChannelsListProps>(channelsListPropsSchema);
5 changes: 4 additions & 1 deletion packages/rest-typings/src/v1/channels/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { ChannelsArchiveProps } from './ChannelsArchiveProps';
import type { ChannelsConvertToTeamProps } from './ChannelsConvertToTeamProps';
import type { ChannelsCreateProps } from './ChannelsCreateProps';
import type { ChannelsDeleteProps } from './ChannelsDeleteProps';
import type { ChannelsFilesListProps } from './ChannelsFilesListProps';
import type { ChannelsGetAllUserMentionsByChannelProps } from './ChannelsGetAllUserMentionsByChannelProps';
import type { ChannelsGetIntegrationsProps } from './ChannelsGetIntegrationsProps';
import type { ChannelsHistoryProps } from './ChannelsHistoryProps';
Expand All @@ -32,9 +33,11 @@ import type { ChannelsSetTopicProps } from './ChannelsSetTopicProps';
import type { ChannelsSetTypeProps } from './ChannelsSetTypeProps';
import type { ChannelsUnarchiveProps } from './ChannelsUnarchiveProps';

export * from './ChannelsFilesListProps';

export type ChannelsEndpoints = {
'/v1/channels.files': {
GET: (params: PaginatedRequest<{ roomId: string } | { roomName: string }>) => PaginatedResult<{
GET: (params: ChannelsFilesListProps) => PaginatedResult<{
files: IUploadWithUser[];
}>;
};
Expand Down

0 comments on commit 4b64cf7

Please sign in to comment.