From 22ad0dc29a86433dca1149a350cdc0a7d397e1d9 Mon Sep 17 00:00:00 2001 From: ahmed-n-abdeltwab Date: Mon, 25 Aug 2025 16:20:29 +0300 Subject: [PATCH 1/3] feat: add openapi support for e2e.getUsersOfRoomWithoutKey api --- apps/meteor/app/api/server/v1/e2e.ts | 124 +++++++++++++++++++-------- 1 file changed, 86 insertions(+), 38 deletions(-) diff --git a/apps/meteor/app/api/server/v1/e2e.ts b/apps/meteor/app/api/server/v1/e2e.ts index 3686f2a7b9007..957229e431f12 100644 --- a/apps/meteor/app/api/server/v1/e2e.ts +++ b/apps/meteor/app/api/server/v1/e2e.ts @@ -1,9 +1,9 @@ +import type { IUser } from '@rocket.chat/core-typings'; import { Subscriptions, Users } from '@rocket.chat/models'; import { ajv, validateUnauthorizedErrorResponse, validateBadRequestErrorResponse, - ise2eGetUsersOfRoomWithoutKeyParamsGET, ise2eSetUserPublicAndPrivateKeysParamsPOST, ise2eUpdateGroupKeyParamsPOST, isE2EProvideUsersGroupKeyProps, @@ -34,6 +34,10 @@ type E2eSetRoomKeyIdProps = { keyID: string; }; +type e2eGetUsersOfRoomWithoutKeyParamsGET = { + rid: string; +}; + const E2eSetRoomKeyIdSchema = { type: 'object', properties: { @@ -48,60 +52,104 @@ const E2eSetRoomKeyIdSchema = { additionalProperties: false, }; +const e2eGetUsersOfRoomWithoutKeyParamsGETSchema = { + type: 'object', + properties: { + rid: { + type: 'string', + }, + }, + additionalProperties: false, + required: ['rid'], +}; + const isE2eSetRoomKeyIdProps = ajv.compile(E2eSetRoomKeyIdSchema); -const e2eEndpoints = API.v1.post( - 'e2e.setRoomKeyID', - { - authRequired: true, - body: isE2eSetRoomKeyIdProps, - response: { - 400: validateBadRequestErrorResponse, - 401: validateUnauthorizedErrorResponse, - 200: ajv.compile({ - type: 'object', - properties: { - success: { type: 'boolean', enum: [true] }, - }, - required: ['success'], - }), +const ise2eGetUsersOfRoomWithoutKeyParamsGET = ajv.compile( + e2eGetUsersOfRoomWithoutKeyParamsGETSchema, +); + +const e2eEndpoints = API.v1 + .post( + 'e2e.setRoomKeyID', + { + authRequired: true, + body: isE2eSetRoomKeyIdProps, + response: { + 400: validateBadRequestErrorResponse, + 401: validateUnauthorizedErrorResponse, + 200: ajv.compile({ + type: 'object', + properties: { + success: { type: 'boolean', enum: [true] }, + }, + required: ['success'], + }), + }, }, - }, - async function action() { - const { rid, keyID } = this.bodyParams; + async function action() { + const { rid, keyID } = this.bodyParams; - await setRoomKeyIDMethod(this.userId, rid, keyID); + await setRoomKeyIDMethod(this.userId, rid, keyID); - return API.v1.success(); - }, -); + return API.v1.success(); + }, + ) + .get( + 'e2e.getUsersOfRoomWithoutKey', + { + authRequired: true, + query: ise2eGetUsersOfRoomWithoutKeyParamsGET, + response: { + 400: validateBadRequestErrorResponse, + 401: validateUnauthorizedErrorResponse, + 200: ajv.compile<{ + users: Pick[]; + }>({ + type: 'object', + properties: { + users: { + type: 'array', + items: { + type: 'object', + properties: { + _id: { type: 'string' }, + e2e: { + type: 'object', + properties: { + private_key: { type: 'string' }, + public_key: { type: 'string' }, + }, + }, + }, + required: ['_id'], + }, + }, + success: { type: 'boolean', enum: [true] }, + }, + required: ['users', 'success'], + }), + }, + }, -API.v1.addRoute( - 'e2e.fetchMyKeys', - { - authRequired: true, - }, - { - async get() { - const result = await Users.fetchKeysByUserId(this.userId); + async function action() { + const { rid } = this.queryParams; + + const result = await getUsersOfRoomWithoutKeyMethod(this.userId, rid); return API.v1.success(result); }, - }, -); + ); API.v1.addRoute( - 'e2e.getUsersOfRoomWithoutKey', + 'e2e.fetchMyKeys', { authRequired: true, - validateParams: ise2eGetUsersOfRoomWithoutKeyParamsGET, }, { async get() { - const { rid } = this.queryParams; - - const result = await getUsersOfRoomWithoutKeyMethod(this.userId, rid); + const result = await Users.fetchKeysByUserId(this.userId); return API.v1.success(result); }, From 20fee797e26acbf4c5a482c2b1e717b1e17ab044 Mon Sep 17 00:00:00 2001 From: ahmed-n-abdeltwab Date: Mon, 25 Aug 2025 16:20:45 +0300 Subject: [PATCH 2/3] refactor: remove unused e2e getUsersOfRoomWithoutKey from rest-typings --- packages/rest-typings/src/index.ts | 1 - packages/rest-typings/src/v1/e2e.ts | 5 ---- .../e2eGetUsersOfRoomWithoutKeyParamsGET.ts | 24 ------------------- 3 files changed, 30 deletions(-) delete mode 100644 packages/rest-typings/src/v1/e2e/e2eGetUsersOfRoomWithoutKeyParamsGET.ts diff --git a/packages/rest-typings/src/index.ts b/packages/rest-typings/src/index.ts index 4f11ad9baf02e..e2b136f834922 100644 --- a/packages/rest-typings/src/index.ts +++ b/packages/rest-typings/src/index.ts @@ -248,7 +248,6 @@ export * from './v1/server-events'; export * from './v1/autotranslate/AutotranslateGetSupportedLanguagesParamsGET'; export * from './v1/autotranslate/AutotranslateSaveSettingsParamsPOST'; export * from './v1/autotranslate/AutotranslateTranslateMessageParamsPOST'; -export * from './v1/e2e/e2eGetUsersOfRoomWithoutKeyParamsGET'; export * from './v1/e2e/e2eSetUserPublicAndPrivateKeysParamsPOST'; export * from './v1/e2e/e2eUpdateGroupKeyParamsPOST'; export * from './v1/e2e'; diff --git a/packages/rest-typings/src/v1/e2e.ts b/packages/rest-typings/src/v1/e2e.ts index 7c7bd8a1d1a66..a42650ff2b59a 100644 --- a/packages/rest-typings/src/v1/e2e.ts +++ b/packages/rest-typings/src/v1/e2e.ts @@ -152,11 +152,6 @@ export type E2eEndpoints = { '/v1/e2e.setUserPublicAndPrivateKeys': { POST: (params: E2eSetUserPublicAndPrivateKeysProps) => void; }; - '/v1/e2e.getUsersOfRoomWithoutKey': { - GET: (params: E2eGetUsersOfRoomWithoutKeyProps) => { - users: Pick[]; - }; - }; '/v1/e2e.updateGroupKey': { POST: (params: E2eUpdateGroupKeyProps) => void; }; diff --git a/packages/rest-typings/src/v1/e2e/e2eGetUsersOfRoomWithoutKeyParamsGET.ts b/packages/rest-typings/src/v1/e2e/e2eGetUsersOfRoomWithoutKeyParamsGET.ts deleted file mode 100644 index 8be9abf23bec3..0000000000000 --- a/packages/rest-typings/src/v1/e2e/e2eGetUsersOfRoomWithoutKeyParamsGET.ts +++ /dev/null @@ -1,24 +0,0 @@ -import Ajv from 'ajv'; - -const ajv = new Ajv({ - coerceTypes: true, -}); - -export type e2eGetUsersOfRoomWithoutKeyParamsGET = { - rid: string; -}; - -const e2eGetUsersOfRoomWithoutKeyParamsGETSchema = { - type: 'object', - properties: { - rid: { - type: 'string', - }, - }, - additionalProperties: false, - required: ['rid'], -}; - -export const ise2eGetUsersOfRoomWithoutKeyParamsGET = ajv.compile( - e2eGetUsersOfRoomWithoutKeyParamsGETSchema, -); From cd03c2b5feda3feafb7f11872c6e69f230919acf Mon Sep 17 00:00:00 2001 From: Ahmed Nasser Date: Mon, 25 Aug 2025 16:25:07 +0300 Subject: [PATCH 3/3] Create nice-squids-smoke.md --- .changeset/nice-squids-smoke.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/nice-squids-smoke.md diff --git a/.changeset/nice-squids-smoke.md b/.changeset/nice-squids-smoke.md new file mode 100644 index 0000000000000..a71f10d915f97 --- /dev/null +++ b/.changeset/nice-squids-smoke.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/rest-typings": patch +--- + +Add OpenAPI support for the Rocket.Chat e2e.getUsersOfRoomWithoutKey endpoints by migrating to a modern chained route definition syntax and utilizing shared AJV schemas for validation to enhance API documentation and ensure type safety through response validation.