Skip to content

Commit

Permalink
chore!: make integrations stop to use query param (#33558)
Browse files Browse the repository at this point in the history
Co-authored-by: Guilherme Gazzo <guilhermegazzo@gmail.com>
  • Loading branch information
ricardogarim and ggazzo committed Oct 17, 2024
1 parent b696246 commit 325d291
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 7 deletions.
2 changes: 1 addition & 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,7 @@ 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/custom-user-status.list'].includes(route);
const hasSupportedRoutes = ['/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
16 changes: 13 additions & 3 deletions apps/meteor/app/api/server/v1/integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
isIntegrationsRemoveProps,
isIntegrationsGetProps,
isIntegrationsUpdateProps,
isIntegrationsListProps,
} from '@rocket.chat/rest-typings';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { Match, check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
import type { Filter } from 'mongodb';
Expand Down Expand Up @@ -86,6 +88,7 @@ API.v1.addRoute(
'integrations.list',
{
authRequired: true,
validateParams: isIntegrationsListProps,
permissionsRequired: {
GET: {
permissions: [
Expand All @@ -101,15 +104,22 @@ API.v1.addRoute(
{
async get() {
const { offset, count } = await getPaginationItems(this.queryParams);
const { sort, fields: projection, query } = await this.parseJsonQuery();
const { sort, fields, query } = await this.parseJsonQuery();
const { name, type } = this.queryParams;

const filter = {
...query,
...(name ? { name: { $regex: escapeRegExp(name as string), $options: 'i' } } : {}),
...(type ? { type } : {}),
};

const ourQuery = Object.assign(await mountIntegrationQueryBasedOnPermissions(this.userId), query) as Filter<IIntegration>;
const ourQuery = Object.assign(await mountIntegrationQueryBasedOnPermissions(this.userId), filter) as Filter<IIntegration>;

const { cursor, totalCount } = Integrations.findPaginated(ourQuery, {
sort: sort || { ts: -1 },
skip: offset,
limit: count,
projection,
projection: fields,
});

const [integrations, total] = await Promise.all([cursor.toArray(), totalCount]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const IntegrationsTable = ({ type }: { type?: string }) => {
const query = useDebouncedValue(
useMemo(
() => ({
query: JSON.stringify({ name: { $regex: escapeRegExp(text), $options: 'i' }, type }),
name: escapeRegExp(text),
type,
sort: `{ "${sortBy}": ${sortDirection === 'asc' ? 1 : -1} }`,
count: itemsPerPage,
offset: current,
Expand Down
41 changes: 41 additions & 0 deletions packages/rest-typings/src/v1/integrations/IntegrationsListProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import Ajv from 'ajv';

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

const ajv = new Ajv();

export type IntegrationsListProps = PaginatedRequest<{ name?: string; type?: string; query?: string }>;

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

export const isIntegrationsListProps = ajv.compile<IntegrationsListProps>(integrationsListSchema);
1 change: 1 addition & 0 deletions packages/rest-typings/src/v1/integrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './IntegrationsHistoryProps';
export * from './IntegrationsRemoveProps';
export * from './IntegrationsGetProps';
export * from './IntegrationsUpdateProps';
export * from './IntegrationsListProps';
4 changes: 2 additions & 2 deletions packages/rest-typings/src/v1/integrations/integrations.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { IIntegration, IIntegrationHistory } from '@rocket.chat/core-typings';

import type { PaginatedRequest } from '../../helpers/PaginatedRequest';
import type { PaginatedResult } from '../../helpers/PaginatedResult';
import type { IntegrationsCreateProps } from './IntegrationsCreateProps';
import type { IntegrationsGetProps } from './IntegrationsGetProps';
import type { IntegrationsHistoryProps } from './IntegrationsHistoryProps';
import type { IntegrationsListProps } from './IntegrationsListProps';
import type { IntegrationsRemoveProps } from './IntegrationsRemoveProps';
import type { IntegrationsUpdateProps } from './IntegrationsUpdateProps';

Expand All @@ -21,7 +21,7 @@ export type IntegrationsEndpoints = {
};

'/v1/integrations.list': {
GET: (params: PaginatedRequest) => PaginatedResult<{
GET: (params: IntegrationsListProps) => PaginatedResult<{
integrations: IIntegration[];
items: number;
}>;
Expand Down

0 comments on commit 325d291

Please sign in to comment.