diff --git a/.changeset/migrate-rooms-leave-endpoint.md b/.changeset/migrate-rooms-leave-endpoint.md new file mode 100644 index 0000000000000..4f9a6263a9a19 --- /dev/null +++ b/.changeset/migrate-rooms-leave-endpoint.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/meteor': minor +'@rocket.chat/rest-typings': minor +--- + +Migrated rooms.leave endpoint to new OpenAPI pattern with AJV validation diff --git a/apps/meteor/app/api/server/v1/rooms.ts b/apps/meteor/app/api/server/v1/rooms.ts index 988e60002eef9..70875e47fedd9 100644 --- a/apps/meteor/app/api/server/v1/rooms.ts +++ b/apps/meteor/app/api/server/v1/rooms.ts @@ -390,23 +390,6 @@ API.v1.addRoute( }, ); -API.v1.addRoute( - 'rooms.leave', - { authRequired: true }, - { - async post() { - const room = await findRoomByIdOrName({ params: this.bodyParams }); - const user = await Users.findOneById(this.userId); - if (!user) { - return API.v1.failure('Invalid user'); - } - await leaveRoomMethod(user, room._id); - - return API.v1.success(); - }, - }, -); - /* TO-DO: 8.0.0 should use the ajv validation which will change this endpoint's @@ -935,6 +918,14 @@ type RoomsFavorite = favorite: boolean; }; +type RoomsLeave = + | { + roomId: string; + } + | { + roomName: string; + }; + const isRoomGetRolesPropsSchema = { type: 'object', properties: { @@ -967,7 +958,29 @@ const RoomsFavoriteSchema = { ], }; +const isRoomsLeavePropsSchema = { + anyOf: [ + { + type: 'object', + properties: { + roomId: { type: 'string' }, + }, + required: ['roomId'], + additionalProperties: false, + }, + { + type: 'object', + properties: { + roomName: { type: 'string' }, + }, + required: ['roomName'], + additionalProperties: false, + }, + ], +}; + const isRoomsFavoriteProps = ajv.compile(RoomsFavoriteSchema); +const isRoomsLeaveProps = ajv.compile(isRoomsLeavePropsSchema); export const roomEndpoints = API.v1 .get( @@ -1141,6 +1154,38 @@ export const roomEndpoints = API.v1 await toggleFavoriteMethod(this.userId, room._id, favorite); + return API.v1.success(); + }, + ) + .post( + 'rooms.leave', + { + authRequired: true, + body: isRoomsLeaveProps, + response: { + 200: ajv.compile({ + type: 'object', + properties: { + success: { type: 'boolean', enum: [true] }, + }, + required: ['success'], + additionalProperties: false, + }), + 400: validateBadRequestErrorResponse, + 401: validateUnauthorizedErrorResponse, + }, + }, + async function action() { + const room = await findRoomByIdOrName({ params: this.bodyParams }); + + const user = await Users.findOneById(this.userId); + + if (!user) { + return API.v1.failure('error-invalid-user'); + } + + await leaveRoomMethod(user, room._id); + return API.v1.success(); }, ); diff --git a/packages/rest-typings/src/v1/rooms.ts b/packages/rest-typings/src/v1/rooms.ts index 18c4574f7bb23..be2314d65bd41 100644 --- a/packages/rest-typings/src/v1/rooms.ts +++ b/packages/rest-typings/src/v1/rooms.ts @@ -90,7 +90,6 @@ export const isRoomsAutocompleteAdminRoomsPayload = ajv.compile void; - }; - '/v1/rooms.getDiscussions': { GET: (params: RoomsGetDiscussionsProps) => PaginatedResult<{ discussions: IRoom[];