From 276a560b08c802ccea91fa51ee597eda1bd0c789 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 10 Mar 2026 00:12:38 +0530 Subject: [PATCH 1/5] chore: migrate users.getStatus endpoint to new OpenAPI pattern with AJV validation --- apps/meteor/app/api/server/v1/users.ts | 75 ++++++++++++++------------ 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/apps/meteor/app/api/server/v1/users.ts b/apps/meteor/app/api/server/v1/users.ts index 50c65abcd8d12..827794fe6b155 100644 --- a/apps/meteor/app/api/server/v1/users.ts +++ b/apps/meteor/app/api/server/v1/users.ts @@ -19,7 +19,7 @@ import { isUsersCheckUsernameAvailabilityParamsGET, isUsersSendConfirmationEmailParamsPOST, ajv, - validateBadRequestErrorResponse, + validateForbiddenErrorResponse, validateUnauthorizedErrorResponse, } from '@rocket.chat/rest-typings'; import { getLoginExpirationInMs, wrapExceptions } from '@rocket.chat/tools'; @@ -878,6 +878,47 @@ const usersEndpoints = API.v1 return API.v1.success({ suggestions }); }, + ) + .get( + 'users.getStatus', + { + authRequired: true, + response: { + 401: validateUnauthorizedErrorResponse, + 200: ajv.compile<{ + _id?: string; + status: 'online' | 'offline' | 'away' | 'busy'; + connectionStatus?: 'online' | 'offline' | 'away' | 'busy'; + }>({ + type: 'object', + properties: { + success: { type: 'boolean', enum: [true] }, + _id: { type: 'string' }, + status: { type: 'string', enum: ['online', 'offline', 'away', 'busy'] }, + connectionStatus: { type: 'string', enum: ['online', 'offline', 'away', 'busy'] }, + }, + required: ['success', 'status'], + additionalProperties: false, + }), + }, + }, + async function action() { + if (isUserFromParams(this.queryParams, this.userId, this.user)) { + const user: IUser | null = await Users.findOneById(this.userId); + return API.v1.success({ + _id: user?._id, + connectionStatus: (user?.statusConnection || 'offline') as 'online' | 'offline' | 'away' | 'busy', + status: (user?.status || 'offline') as 'online' | 'offline' | 'away' | 'busy', + }); + } + + const user = await getUserFromParams(this.queryParams); + + return API.v1.success({ + _id: user._id, + status: (user.status || 'offline') as 'online' | 'offline' | 'away' | 'busy', + }); + }, ); API.v1.addRoute( @@ -1517,38 +1558,6 @@ API.v1.addRoute( }, ); -// status: 'online' | 'offline' | 'away' | 'busy'; -// message?: string; -// _id: string; -// connectionStatus?: 'online' | 'offline' | 'away' | 'busy'; -// }; - -API.v1.addRoute( - 'users.getStatus', - { authRequired: true }, - { - async get() { - if (isUserFromParams(this.queryParams, this.userId, this.user)) { - const user: IUser | null = await Users.findOneById(this.userId); - return API.v1.success({ - _id: user?._id, - // message: user.statusText, - connectionStatus: (user?.statusConnection || 'offline') as 'online' | 'offline' | 'away' | 'busy', - status: (user?.status || 'offline') as 'online' | 'offline' | 'away' | 'busy', - }); - } - - const user = await getUserFromParams(this.queryParams); - - return API.v1.success({ - _id: user._id, - // message: user.statusText, - status: (user.status || 'offline') as 'online' | 'offline' | 'away' | 'busy', - }); - }, - }, -); - settings.watch('Rate_Limiter_Limit_RegisterUser', (value) => { const userRegisterRoute = '/api/v1/users.registerpost'; From 06134136b037f428751c344255f8075cec424851 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 10 Mar 2026 00:13:32 +0530 Subject: [PATCH 2/5] chore: migrate users.getStatus endpoint to new OpenAPI pattern with AJV validation --- packages/rest-typings/src/v1/users.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/rest-typings/src/v1/users.ts b/packages/rest-typings/src/v1/users.ts index 565620d31ba5e..c833ab1758064 100644 --- a/packages/rest-typings/src/v1/users.ts +++ b/packages/rest-typings/src/v1/users.ts @@ -318,15 +318,6 @@ export type UsersEndpoints = { POST: (params: { message?: string; status?: UserStatus; userId?: string; username?: string; user?: string }) => void; }; - '/v1/users.getStatus': { - GET: () => { - status: 'online' | 'offline' | 'away' | 'busy'; - message?: string; - _id?: string; - connectionStatus?: 'online' | 'offline' | 'away' | 'busy'; - }; - }; - '/v1/users.info': { GET: (params: UsersInfoParamsGet) => { user: IUser & { rooms?: Pick[] }; From f2e2d20fd2df0b475e2cf747a836ea902788e9f1 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 10 Mar 2026 00:15:56 +0530 Subject: [PATCH 3/5] Create migrate-users-getStatus-openapi.md --- .changeset/migrate-users-getStatus-openapi.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/migrate-users-getStatus-openapi.md diff --git a/.changeset/migrate-users-getStatus-openapi.md b/.changeset/migrate-users-getStatus-openapi.md new file mode 100644 index 0000000000000..1433fcfced623 --- /dev/null +++ b/.changeset/migrate-users-getStatus-openapi.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/rest-typings": patch +--- + +Migrates the `users.getStatus` REST API endpoint from the legacy `API.v1.addRoute` pattern to the new chained `API.v1.get()` pattern with AJV response schema validation and OpenAPI documentation support. From 7a0764218ceb70327ed0f3b9a2981f45eed9ca2b Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 10 Mar 2026 00:28:39 +0530 Subject: [PATCH 4/5] fix: remove unused validateForbiddenErrorResponse import --- apps/meteor/app/api/server/v1/users.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/api/server/v1/users.ts b/apps/meteor/app/api/server/v1/users.ts index 827794fe6b155..b7db7095644d0 100644 --- a/apps/meteor/app/api/server/v1/users.ts +++ b/apps/meteor/app/api/server/v1/users.ts @@ -19,7 +19,7 @@ import { isUsersCheckUsernameAvailabilityParamsGET, isUsersSendConfirmationEmailParamsPOST, ajv, - validateForbiddenErrorResponse, + validateBadRequestErrorResponse, validateUnauthorizedErrorResponse, } from '@rocket.chat/rest-typings'; import { getLoginExpirationInMs, wrapExceptions } from '@rocket.chat/tools'; From f8b7afc373032d63df4eb3817aecac2a23834218 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 10 Mar 2026 15:39:22 +0530 Subject: [PATCH 5/5] fix(users.getStatus): include message property in response schema --- apps/meteor/app/api/server/v1/users.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/meteor/app/api/server/v1/users.ts b/apps/meteor/app/api/server/v1/users.ts index b7db7095644d0..ea80482f20954 100644 --- a/apps/meteor/app/api/server/v1/users.ts +++ b/apps/meteor/app/api/server/v1/users.ts @@ -889,6 +889,7 @@ const usersEndpoints = API.v1 _id?: string; status: 'online' | 'offline' | 'away' | 'busy'; connectionStatus?: 'online' | 'offline' | 'away' | 'busy'; + message?: string; }>({ type: 'object', properties: { @@ -896,6 +897,7 @@ const usersEndpoints = API.v1 _id: { type: 'string' }, status: { type: 'string', enum: ['online', 'offline', 'away', 'busy'] }, connectionStatus: { type: 'string', enum: ['online', 'offline', 'away', 'busy'] }, + message: { type: 'string' }, }, required: ['success', 'status'], additionalProperties: false, @@ -909,6 +911,7 @@ const usersEndpoints = API.v1 _id: user?._id, connectionStatus: (user?.statusConnection || 'offline') as 'online' | 'offline' | 'away' | 'busy', status: (user?.status || 'offline') as 'online' | 'offline' | 'away' | 'busy', + message: user?.statusText, }); } @@ -917,6 +920,7 @@ const usersEndpoints = API.v1 return API.v1.success({ _id: user._id, status: (user.status || 'offline') as 'online' | 'offline' | 'away' | 'busy', + message: user?.statusText, }); }, );