From bef789d5142f2250a0f5cf93221ebb88ffddafba Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Sun, 1 Mar 2026 19:16:48 +0530 Subject: [PATCH 01/22] feat(rest): migrate /api/v1/me to OpenAPI endpoint definition - Replace legacy API.v1.addRoute with API.v1.get - Add AJV response validation schema - Export MeEndpoints using ExtractRoutesFromAPI - Extend @rocket.chat/rest-typings Endpoints interface - Enable OpenAPI/Swagger schema generation --- apps/meteor/app/api/server/v1/misc.ts | 39 ++++++++++++++++++++------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 852351a3c5ded..4ba622f975ccb 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -17,6 +17,9 @@ import { check } from 'meteor/check'; import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'; import { Meteor } from 'meteor/meteor'; +import { ajv } from '../../../lib/ajv'; +import { validateUnauthorizedErrorResponse } from '../../../lib/rest/validators'; +import { ExtractRoutesFromAPI } from '../../../lib/rest/typings'; import { i18n } from '../../../../server/lib/i18n'; import { SystemLogger } from '../../../../server/lib/logger/system'; import { browseChannelsMethod } from '../../../../server/methods/browseChannels'; @@ -169,18 +172,36 @@ import { getUserInfo } from '../helpers/getUserInfo'; * schema: * $ref: '#/components/schemas/ApiFailureV1' */ -API.v1.addRoute( +const meEndpoints = API.v1.get( 'me', - { authRequired: true }, { - async get() { - const userFields = { ...getBaseUserFields(), services: 1 }; - const user = (await Users.findOneById(this.userId, { projection: userFields })) as IUser; - - return API.v1.success(await getUserInfo(user)); - }, + authRequired: true, + query: undefined, + response: { + 401: validateUnauthorizedErrorResponse, + 200: ajv.compile({ + type: 'object', + properties: { + success: { type: 'boolean', enum: [true] } + }, + required: ['success'], + additionalProperties: true + }) + } }, -); + async function action() { + const userFields = { ...getBaseUserFields(), services: 1 }; + const user = (await Users.findOneById(this.userId, { projection: userFields })) as IUser; + + return API.v1.success(await getUserInfo(user)); + } +}; + +export type MeEndpoints = ExtractRoutesFromAPI; + +declare module '@rocket.chat/rest-typings' { + interface Endpoints extends MeEndpoints {} +} let onlineCache = 0; let onlineCacheDate = 0; From 0aa1367276109eb6ddf44318a413b06b1cb256d7 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Sun, 1 Mar 2026 19:29:10 +0530 Subject: [PATCH 02/22] fix(rest): correct closing delimiter in me endpoint migration --- apps/meteor/app/api/server/v1/misc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 4ba622f975ccb..4683932810c46 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -195,7 +195,7 @@ const meEndpoints = API.v1.get( return API.v1.success(await getUserInfo(user)); } -}; +); export type MeEndpoints = ExtractRoutesFromAPI; From 8f00741a30e8a678f9c9a6661f00befbf008c290 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Sun, 1 Mar 2026 21:26:09 +0530 Subject: [PATCH 03/22] Update misc.ts --- apps/meteor/app/api/server/v1/misc.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 4683932810c46..60a6a242de020 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -176,15 +176,16 @@ const meEndpoints = API.v1.get( 'me', { authRequired: true, - query: undefined, response: { 401: validateUnauthorizedErrorResponse, 200: ajv.compile({ type: 'object', properties: { - success: { type: 'boolean', enum: [true] } + success: { type: 'boolean', enum: [true] }, + _id: { type: 'string' }, + username: {type: 'string' } }, - required: ['success'], + required: ['success', '_id', 'username'], additionalProperties: true }) } From 4277bb21dfdfe7482bd444e43c73a8e31dff796a Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 11:05:07 +0530 Subject: [PATCH 04/22] update /api/v1/me endpoint with AJV schema and TypeScript interface --- apps/meteor/app/api/server/v1/misc.ts | 268 ++++++++++---------------- 1 file changed, 107 insertions(+), 161 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 60a6a242de020..2c26491bcad6f 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -10,6 +10,9 @@ import { isMethodCallAnonProps, isFingerprintProps, isMeteorCall, + ajv, + validateUnauthorizedErrorResponse, + ExtractRoutesFromAPI } from '@rocket.chat/rest-typings'; import { escapeHTML } from '@rocket.chat/string-helpers'; import EJSON from 'ejson'; @@ -17,9 +20,6 @@ import { check } from 'meteor/check'; import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'; import { Meteor } from 'meteor/meteor'; -import { ajv } from '../../../lib/ajv'; -import { validateUnauthorizedErrorResponse } from '../../../lib/rest/validators'; -import { ExtractRoutesFromAPI } from '../../../lib/rest/typings'; import { i18n } from '../../../../server/lib/i18n'; import { SystemLogger } from '../../../../server/lib/logger/system'; import { browseChannelsMethod } from '../../../../server/methods/browseChannels'; @@ -37,171 +37,117 @@ import { getUserFromParams } from '../helpers/getUserFromParams'; import { getUserInfo } from '../helpers/getUserInfo'; /** - * @openapi - * /api/v1/me: - * get: - * description: Gets user data of the authenticated user - * security: - * - authenticated: [] - * responses: - * 200: - * description: The user data of the authenticated user - * content: - * application/json: - * schema: - * allOf: - * - $ref: '#/components/schemas/ApiSuccessV1' - * - type: object - * properties: - * name: - * type: string - * username: - * type: string - * nickname: - * type: string - * emails: - * type: array - * items: - * type: object - * properties: - * address: - * type: string - * verified: - * type: boolean - * email: - * type: string - * status: - * $ref: '#/components/schemas/UserStatus' - * statusDefault: - * $ref: '#/components/schemas/UserStatus' - * statusText: - * $ref: '#/components/schemas/UserStatus' - * statusConnection: - * $ref: '#/components/schemas/UserStatus' - * bio: - * type: string - * avatarOrigin: - * type: string - * enum: [none, local, upload, url] - * utcOffset: - * type: number - * language: - * type: string - * settings: - * type: object - * properties: - * preferences: - * type: object - * enableAutoAway: - * type: boolean - * idleTimeLimit: - * type: number - * roles: - * type: array - * active: - * type: boolean - * defaultRoom: - * type: string - * customFields: - * type: array - * requirePasswordChange: - * type: boolean - * requirePasswordChangeReason: - * type: string - * services: - * type: object - * properties: - * github: - * type: object - * gitlab: - * type: object - * password: - * type: object - * properties: - * exists: - * type: boolean - * totp: - * type: object - * properties: - * enabled: - * type: boolean - * email2fa: - * type: object - * properties: - * enabled: - * type: boolean - * statusLivechat: - * type: string - * enum: [available, 'not-available'] - * banners: - * type: array - * items: - * type: object - * properties: - * id: - * type: string - * title: - * type: string - * text: - * type: string - * textArguments: - * type: array - * items: {} - * modifiers: - * type: array - * items: - * type: string - * infoUrl: - * type: string - * oauth: - * type: object - * properties: - * authorizedClients: - * type: array - * items: - * type: string - * _updatedAt: - * type: string - * format: date-time - * avatarETag: - * type: string - * default: - * description: Unexpected error - * content: - * application/json: - * schema: - * $ref: '#/components/schemas/ApiFailureV1' + * ------------------------- + * /api/v1/me endpoint schema + * ------------------------- */ -const meEndpoints = API.v1.get( - 'me', - { - authRequired: true, - response: { - 401: validateUnauthorizedErrorResponse, - 200: ajv.compile({ - type: 'object', - properties: { - success: { type: 'boolean', enum: [true] }, - _id: { type: 'string' }, - username: {type: 'string' } - }, - required: ['success', '_id', 'username'], - additionalProperties: true - }) - } - }, - async function action() { - const userFields = { ...getBaseUserFields(), services: 1 }; - const user = (await Users.findOneById(this.userId, { projection: userFields })) as IUser; +export interface IMeResponse { + success: true; + _id: string; + name: string; + username: string; + nickname: string; + emails: Array<{ address: string; verified: boolean }>; + email: string; + status: string; + statusDefault: string; + statusText: string; + statusConnection: string; + bio: string; + avatarOrigin: 'none' | 'local' | 'upload' | 'url'; + utcOffset: number; + language: string; + settings: { preferences?: Record }; + enableAutoAway: boolean; + idleTimeLimit: number; + roles: string[]; + active: boolean; + defaultRoom: string; + customFields: unknown[]; + requirePasswordChange: boolean; + requirePasswordChangeReason: string; + services: Record; + statusLivechat: 'available' | 'not-available'; + banners: Array>; + oauth: { authorizedClients?: string[] }; + _updatedAt: string; + avatarETag: string; +} - return API.v1.success(await getUserInfo(user)); - } +export const meResponseSchema = { + type: 'object', + properties: { + success: { type: 'boolean', enum: [true] }, + _id: { type: 'string' }, + name: { type: 'string' }, + username: { type: 'string' }, + nickname: { type: 'string' }, + emails: { + type: 'array', + items: { type: 'object', properties: { address: { type: 'string' }, verified: { type: 'boolean' } }, required: ['address', 'verified'], additionalProperties: false }, + }, + email: { type: 'string' }, + status: { type: 'string' }, + statusDefault: { type: 'string' }, + statusText: { type: 'string' }, + statusConnection: { type: 'string' }, + bio: { type: 'string' }, + avatarOrigin: { type: 'string', enum: ['none', 'local', 'upload', 'url'] }, + utcOffset: { type: 'number' }, + language: { type: 'string' }, + settings: { type: 'object', additionalProperties: true }, + enableAutoAway: { type: 'boolean' }, + idleTimeLimit: { type: 'number' }, + roles: { type: 'array', items: { type: 'string' } }, + active: { type: 'boolean' }, + defaultRoom: { type: 'string' }, + customFields: { type: 'array', items: {} }, + requirePasswordChange: { type: 'boolean' }, + requirePasswordChangeReason: { type: 'string' }, + services: { type: 'object', additionalProperties: true }, + statusLivechat: { type: 'string', enum: ['available', 'not-available'] }, + banners: { type: 'array', items: { type: 'object', additionalProperties: true } }, + oauth: { type: 'object', additionalProperties: true }, + _updatedAt: { type: 'string', format: 'date-time' }, + avatarETag: { type: 'string' }, + }, + required: [ + 'success', '_id', 'name', 'username', 'nickname', 'emails', 'email', + 'status', 'statusDefault', 'statusText', 'statusConnection', 'bio', + 'avatarOrigin', 'utcOffset', 'language', 'settings', 'enableAutoAway', + 'idleTimeLimit', 'roles', 'active', 'defaultRoom', 'customFields', + 'requirePasswordChange', 'requirePasswordChangeReason', 'services', + 'statusLivechat', 'banners', 'oauth', '_updatedAt', 'avatarETag', + ], + additionalProperties: true, +} as const; + +/** + * -------------------------------- + * /api/v1/me endpoint + * -------------------------------- + */ +const meEndpoints = API.v1.get( + 'me', + { + authRequired: true, + response: { + 401: validateUnauthorizedErrorResponse, + 200: ajv.compile(meResponseSchema), + }, + }, +async function action() { + const userFields = { ...getBaseUserFields(), services: 1 }; + const user = (await Users.findOneById(this.userId, { projection: userFields })) as IUser; + + return API.v1.success(await getUserInfo(user)); + }, ); export type MeEndpoints = ExtractRoutesFromAPI; declare module '@rocket.chat/rest-typings' { - interface Endpoints extends MeEndpoints {} + interface Endpoints extends MeEndpoints {} } let onlineCache = 0; From 310c2e42a10a146e7126869a9b65778364629024 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 11:13:45 +0530 Subject: [PATCH 05/22] '@rocket.chat/rest-typings': minor Updated /api/v1/me endpoint: removed old @openapi block, added detected AJV schema and TypeScript interface, and cleaned up rest-typings imports. --- .changeset/v1-me-endpoint-update.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/v1-me-endpoint-update.md diff --git a/.changeset/v1-me-endpoint-update.md b/.changeset/v1-me-endpoint-update.md new file mode 100644 index 0000000000000..3a40fdb4179ce --- /dev/null +++ b/.changeset/v1-me-endpoint-update.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': minor +'@rocket.chat/rest-typings': minor +--- +Updated /api/v1/me endpoint with AJV schema and TypeScript interface, removed old @openapi block, and cleaned up rest-typings import paths From 5c08dc5addfb14e4e6a6e50adfecdc594db1fb1b Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 11:17:07 +0530 Subject: [PATCH 06/22] refactor(rest-typings): remove old /v1/me endpoint typing in favor of AJV schema --- packages/rest-typings/src/v1/me.ts | 50 +++++------------------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/packages/rest-typings/src/v1/me.ts b/packages/rest-typings/src/v1/me.ts index f9ca62460d74f..9772c52babc75 100644 --- a/packages/rest-typings/src/v1/me.ts +++ b/packages/rest-typings/src/v1/me.ts @@ -1,46 +1,10 @@ -import type { IUser } from '@rocket.chat/core-typings'; +import type { IMeResponse } from '@rocket.chat/rest-api/server/misc'; +import { ExtractRoutesFromAPI } from '@rocket.chat/rest-typings'; +import type { MeEndpoints as MiscMeEndpoints } from '@rocket.chat/rest-api/server/misc'; -type Keys = - | 'name' - | 'username' - | 'nickname' - | 'emails' - | 'status' - | 'statusDefault' - | 'statusText' - | 'statusConnection' - | 'bio' - | 'avatarOrigin' - | 'utcOffset' - | 'language' - | 'settings' - | 'idleTimeLimit' - | 'roles' - | 'active' - | 'defaultRoom' - | 'customFields' - | 'requirePasswordChange' - | 'requirePasswordChangeReason' - | 'services.github' - | 'services.gitlab' - | 'services.password.bcrypt' - | 'services.totp.enabled' - | 'services.email2fa.enabled' - | 'statusLivechat' - | 'banners' - | 'oauth.authorizedClients' - | '_updatedAt' - | 'avatarETag'; +declare module '@rocket.chat/rest-typings' { + interface Endpoints extends ExtractRoutesFromAPI {} +} -export type MeEndpoints = { - '/v1/me': { - GET: (params?: { fields: Record | Record; user: IUser }) => IUser & { - email?: string; - settings?: { - profile: Record; - preferences: unknown; - }; - avatarUrl: string; - }; - }; +export {}; }; From c0e8660328aabf436703d07ea492ed6f4c68ad1a Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 11:20:40 +0530 Subject: [PATCH 07/22] Update misc.ts --- apps/meteor/app/api/server/v1/misc.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 2c26491bcad6f..1607ab58a0ef0 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -48,7 +48,7 @@ export interface IMeResponse { username: string; nickname: string; emails: Array<{ address: string; verified: boolean }>; - email: string; + email?: string; // made optional status: string; statusDefault: string; statusText: string; @@ -63,7 +63,7 @@ export interface IMeResponse { roles: string[]; active: boolean; defaultRoom: string; - customFields: unknown[]; + customFields: Record; // fixed from array requirePasswordChange: boolean; requirePasswordChangeReason: string; services: Record; @@ -86,7 +86,7 @@ export const meResponseSchema = { type: 'array', items: { type: 'object', properties: { address: { type: 'string' }, verified: { type: 'boolean' } }, required: ['address', 'verified'], additionalProperties: false }, }, - email: { type: 'string' }, + email: { type: 'string', nullable: true }, // optional status: { type: 'string' }, statusDefault: { type: 'string' }, statusText: { type: 'string' }, @@ -100,8 +100,8 @@ export const meResponseSchema = { idleTimeLimit: { type: 'number' }, roles: { type: 'array', items: { type: 'string' } }, active: { type: 'boolean' }, - defaultRoom: { type: 'string' }, - customFields: { type: 'array', items: {} }, + defaultRoom: { type: 'string' }, + customFields: { type: 'object', additionalProperties: true }, // fixed requirePasswordChange: { type: 'boolean' }, requirePasswordChangeReason: { type: 'string' }, services: { type: 'object', additionalProperties: true }, @@ -112,16 +112,15 @@ export const meResponseSchema = { avatarETag: { type: 'string' }, }, required: [ - 'success', '_id', 'name', 'username', 'nickname', 'emails', 'email', + 'success', '_id', 'name', 'username', 'nickname', 'emails', 'status', 'statusDefault', 'statusText', 'statusConnection', 'bio', 'avatarOrigin', 'utcOffset', 'language', 'settings', 'enableAutoAway', - 'idleTimeLimit', 'roles', 'active', 'defaultRoom', 'customFields', + 'idleTimeLimit', 'roles', 'active', 'defaultRoom', 'requirePasswordChange', 'requirePasswordChangeReason', 'services', 'statusLivechat', 'banners', 'oauth', '_updatedAt', 'avatarETag', ], - additionalProperties: true, + additionalProperties: true, } as const; - /** * -------------------------------- * /api/v1/me endpoint From 47e28e2a4af61fc3607cafe775e54a87fee9b41c Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 11:40:08 +0530 Subject: [PATCH 08/22] Update me.ts --- packages/rest-typings/src/v1/me.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rest-typings/src/v1/me.ts b/packages/rest-typings/src/v1/me.ts index 9772c52babc75..e37e0ebae51cd 100644 --- a/packages/rest-typings/src/v1/me.ts +++ b/packages/rest-typings/src/v1/me.ts @@ -7,4 +7,3 @@ declare module '@rocket.chat/rest-typings' { } export {}; -}; From 68b3b5100d092e02d76560fcb54edc13a4bf7715 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 11:51:06 +0530 Subject: [PATCH 09/22] Update path of importing file --- packages/rest-typings/src/v1/me.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/rest-typings/src/v1/me.ts b/packages/rest-typings/src/v1/me.ts index e37e0ebae51cd..a4f29fcf07f15 100644 --- a/packages/rest-typings/src/v1/me.ts +++ b/packages/rest-typings/src/v1/me.ts @@ -1,6 +1,5 @@ -import type { IMeResponse } from '@rocket.chat/rest-api/server/misc'; +import type { MeEndpoints as MiscMeEndpoints } from '@rocket.chat/meteor/app/api/server/v1/misc'; import { ExtractRoutesFromAPI } from '@rocket.chat/rest-typings'; -import type { MeEndpoints as MiscMeEndpoints } from '@rocket.chat/rest-api/server/misc'; declare module '@rocket.chat/rest-typings' { interface Endpoints extends ExtractRoutesFromAPI {} From 4b66abfb308775baf0cbda36d827a8a52bc2a6d1 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 15:13:01 +0530 Subject: [PATCH 10/22] Remove the MeEndPoints imports --- packages/rest-typings/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/rest-typings/src/index.ts b/packages/rest-typings/src/index.ts index b0e2dacff7a85..c077796e57969 100644 --- a/packages/rest-typings/src/index.ts +++ b/packages/rest-typings/src/index.ts @@ -28,7 +28,6 @@ import type { InvitesEndpoints } from './v1/invites'; import type { LDAPEndpoints } from './v1/ldap'; import type { LicensesEndpoints } from './v1/licenses'; import type { MailerEndpoints } from './v1/mailer'; -import type { MeEndpoints } from './v1/me'; import type { MiscEndpoints } from './v1/misc'; import type { ModerationEndpoints } from './v1/moderation'; import type { OmnichannelEndpoints } from './v1/omnichannel'; @@ -47,7 +46,6 @@ import type { VideoConferenceEndpoints } from './v1/videoConference'; // eslint-disable-next-line @typescript-eslint/naming-convention export interface Endpoints extends ChannelsEndpoints, - MeEndpoints, ModerationEndpoints, BannersEndpoints, ChatEndpoints, From 253b59c21cae95c083b90058335b049eda452921 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 20:20:15 +0530 Subject: [PATCH 11/22] Update misc.ts --- apps/meteor/app/api/server/v1/misc.ts | 105 +++----------------------- 1 file changed, 9 insertions(+), 96 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 1607ab58a0ef0..a536388c7ec20 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -10,9 +10,7 @@ import { isMethodCallAnonProps, isFingerprintProps, isMeteorCall, - ajv, validateUnauthorizedErrorResponse, - ExtractRoutesFromAPI } from '@rocket.chat/rest-typings'; import { escapeHTML } from '@rocket.chat/string-helpers'; import EJSON from 'ejson'; @@ -36,91 +34,6 @@ import { getPaginationItems } from '../helpers/getPaginationItems'; import { getUserFromParams } from '../helpers/getUserFromParams'; import { getUserInfo } from '../helpers/getUserInfo'; -/** - * ------------------------- - * /api/v1/me endpoint schema - * ------------------------- - */ -export interface IMeResponse { - success: true; - _id: string; - name: string; - username: string; - nickname: string; - emails: Array<{ address: string; verified: boolean }>; - email?: string; // made optional - status: string; - statusDefault: string; - statusText: string; - statusConnection: string; - bio: string; - avatarOrigin: 'none' | 'local' | 'upload' | 'url'; - utcOffset: number; - language: string; - settings: { preferences?: Record }; - enableAutoAway: boolean; - idleTimeLimit: number; - roles: string[]; - active: boolean; - defaultRoom: string; - customFields: Record; // fixed from array - requirePasswordChange: boolean; - requirePasswordChangeReason: string; - services: Record; - statusLivechat: 'available' | 'not-available'; - banners: Array>; - oauth: { authorizedClients?: string[] }; - _updatedAt: string; - avatarETag: string; -} - -export const meResponseSchema = { - type: 'object', - properties: { - success: { type: 'boolean', enum: [true] }, - _id: { type: 'string' }, - name: { type: 'string' }, - username: { type: 'string' }, - nickname: { type: 'string' }, - emails: { - type: 'array', - items: { type: 'object', properties: { address: { type: 'string' }, verified: { type: 'boolean' } }, required: ['address', 'verified'], additionalProperties: false }, - }, - email: { type: 'string', nullable: true }, // optional - status: { type: 'string' }, - statusDefault: { type: 'string' }, - statusText: { type: 'string' }, - statusConnection: { type: 'string' }, - bio: { type: 'string' }, - avatarOrigin: { type: 'string', enum: ['none', 'local', 'upload', 'url'] }, - utcOffset: { type: 'number' }, - language: { type: 'string' }, - settings: { type: 'object', additionalProperties: true }, - enableAutoAway: { type: 'boolean' }, - idleTimeLimit: { type: 'number' }, - roles: { type: 'array', items: { type: 'string' } }, - active: { type: 'boolean' }, - defaultRoom: { type: 'string' }, - customFields: { type: 'object', additionalProperties: true }, // fixed - requirePasswordChange: { type: 'boolean' }, - requirePasswordChangeReason: { type: 'string' }, - services: { type: 'object', additionalProperties: true }, - statusLivechat: { type: 'string', enum: ['available', 'not-available'] }, - banners: { type: 'array', items: { type: 'object', additionalProperties: true } }, - oauth: { type: 'object', additionalProperties: true }, - _updatedAt: { type: 'string', format: 'date-time' }, - avatarETag: { type: 'string' }, - }, - required: [ - 'success', '_id', 'name', 'username', 'nickname', 'emails', - 'status', 'statusDefault', 'statusText', 'statusConnection', 'bio', - 'avatarOrigin', 'utcOffset', 'language', 'settings', 'enableAutoAway', - 'idleTimeLimit', 'roles', 'active', 'defaultRoom', - 'requirePasswordChange', 'requirePasswordChangeReason', 'services', - 'statusLivechat', 'banners', 'oauth', '_updatedAt', 'avatarETag', - ], - additionalProperties: true, -} as const; /** * -------------------------------- * /api/v1/me endpoint @@ -132,23 +45,23 @@ const meEndpoints = API.v1.get( authRequired: true, response: { 401: validateUnauthorizedErrorResponse, - 200: ajv.compile(meResponseSchema), + 200: { + $ref: '#/components/schemas/IUser', + }, }, }, -async function action() { + async function action() { const userFields = { ...getBaseUserFields(), services: 1 }; - const user = (await Users.findOneById(this.userId, { projection: userFields })) as IUser; + const user = await Users.findOneById(this.userId, { projection: userFields }); + + if (!user) { + throw new Meteor.Error('error-invalid-user', 'User not found'); + } return API.v1.success(await getUserInfo(user)); }, ); -export type MeEndpoints = ExtractRoutesFromAPI; - -declare module '@rocket.chat/rest-typings' { - interface Endpoints extends MeEndpoints {} -} - let onlineCache = 0; let onlineCacheDate = 0; const cacheInvalid = 60000; // 1 minute From d8b3558d0629608dd4155d5e7bddbc1cd9c70c6f Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 20:20:27 +0530 Subject: [PATCH 12/22] Update Ajv.ts --- packages/core-typings/src/Ajv.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core-typings/src/Ajv.ts b/packages/core-typings/src/Ajv.ts index eb91852edb6de..9d8d804ab3b3e 100644 --- a/packages/core-typings/src/Ajv.ts +++ b/packages/core-typings/src/Ajv.ts @@ -10,6 +10,7 @@ import type { IPermission } from './IPermission'; import type { ISubscription } from './ISubscription'; import type { SlashCommand } from './SlashCommands'; import type { IMediaCall } from './mediaCalls/IMediaCall'; +import type { IUser } from "./IUser"; export const schemas = typia.json.schemas< [ @@ -17,6 +18,7 @@ export const schemas = typia.json.schemas< CallHistoryItem, ICustomUserStatus, SlashCommand, + IUser ], '3.0' >(); From 9f3ec130e3211c767fc0aa5fc5c9ba77558c83ac Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 20:20:34 +0530 Subject: [PATCH 13/22] Delete packages/rest-typings/src/v1/me.ts --- packages/rest-typings/src/v1/me.ts | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 packages/rest-typings/src/v1/me.ts diff --git a/packages/rest-typings/src/v1/me.ts b/packages/rest-typings/src/v1/me.ts deleted file mode 100644 index a4f29fcf07f15..0000000000000 --- a/packages/rest-typings/src/v1/me.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { MeEndpoints as MiscMeEndpoints } from '@rocket.chat/meteor/app/api/server/v1/misc'; -import { ExtractRoutesFromAPI } from '@rocket.chat/rest-typings'; - -declare module '@rocket.chat/rest-typings' { - interface Endpoints extends ExtractRoutesFromAPI {} -} - -export {}; From 4140f45112e0d78ea69ec15ba45d506886e7de52 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Mon, 2 Mar 2026 22:22:58 +0530 Subject: [PATCH 14/22] fix(api): update /api/v1/me 200 response schema to include success envelope --- apps/meteor/app/api/server/v1/misc.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index a536388c7ec20..60baa0c0de8c0 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -46,7 +46,10 @@ const meEndpoints = API.v1.get( response: { 401: validateUnauthorizedErrorResponse, 200: { - $ref: '#/components/schemas/IUser', + allOf: [ + { $ref: '#/components/schemas/ApiSuccessV1' }, + { $ref: '#/components/schemas/IUser' }, + ], }, }, }, From 4250813dd5b2bfb8155e46bd6814254c408e439f Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 10:16:33 +0530 Subject: [PATCH 15/22] fix(api): update /api/v1/me 200 response schema to include success envelope --- packages/core-typings/src/Ajv.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core-typings/src/Ajv.ts b/packages/core-typings/src/Ajv.ts index 9d8d804ab3b3e..ec508fa1c35f5 100644 --- a/packages/core-typings/src/Ajv.ts +++ b/packages/core-typings/src/Ajv.ts @@ -11,6 +11,7 @@ import type { ISubscription } from './ISubscription'; import type { SlashCommand } from './SlashCommands'; import type { IMediaCall } from './mediaCalls/IMediaCall'; import type { IUser } from "./IUser"; +import type { IMeResponse } from '../../../apps/meteor/app/api/server/v1/misc'; export const schemas = typia.json.schemas< [ @@ -18,7 +19,8 @@ export const schemas = typia.json.schemas< CallHistoryItem, ICustomUserStatus, SlashCommand, - IUser + IUser, + IMeResponse ], '3.0' >(); From ea9adb2dad838280c2ca41879333d1cef89e8917 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 10:16:36 +0530 Subject: [PATCH 16/22] fix(api): update /api/v1/me 200 response schema to include success envelope --- apps/meteor/app/api/server/v1/misc.ts | 49 ++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 60baa0c0de8c0..c81a7146e56e1 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -34,12 +34,45 @@ import { getPaginationItems } from '../helpers/getPaginationItems'; import { getUserFromParams } from '../helpers/getUserFromParams'; import { getUserInfo } from '../helpers/getUserInfo'; +/** + * -------------------------------- + * Types and Schemas + * -------------------------------- + */ + +// Keys allowed in fields query +type Keys = + | 'name' | 'username' | 'nickname' | 'emails' | 'status' | 'statusDefault' + | 'statusText' | 'statusConnection' | 'bio' | 'avatarOrigin' | 'utcOffset' + | 'language' | 'settings' | 'idleTimeLimit' | 'roles' | 'active' | 'defaultRoom' + | 'customFields' | 'requirePasswordChange' | 'requirePasswordChangeReason' + | 'services.github' | 'services.gitlab' | 'services.password.bcrypt' + | 'services.totp.enabled' | 'services.email2fa.enabled' | 'statusLivechat' + | 'banners' | 'oauth.authorizedClients' | '_updatedAt' | 'avatarETag'; + +// Query params type +export type MeParams = { fields: Record | Record; user: IUser }; + +// AJV validation schema +const meSchema = { + type: 'object', + properties: {}, + additionalProperties: false, + required: ['fields', 'user'], +}; +export const isMeProps = ajv.compile(meSchema); + +// Response type +export type IMeResponse = { + success: true; +} & Awaited>; + /** * -------------------------------- * /api/v1/me endpoint * -------------------------------- */ -const meEndpoints = API.v1.get( +export const meEndpoints = API.v1.get( 'me', { authRequired: true, @@ -47,17 +80,17 @@ const meEndpoints = API.v1.get( 401: validateUnauthorizedErrorResponse, 200: { allOf: [ - { $ref: '#/components/schemas/ApiSuccessV1' }, - { $ref: '#/components/schemas/IUser' }, - ], + { $ref: '#/components/schemas/ApiSuccessV1' }, + { $ref: '#/components/schemas/IUser' }, + ], }, }, }, - async function action() { - const userFields = { ...getBaseUserFields(), services: 1 }; - const user = await Users.findOneById(this.userId, { projection: userFields }); +async function action() { + const userFields = { ...getBaseUserFields(), services: 1 }; + const user = await Users.findOneById(this.userId!, { projection: userFields }); - if (!user) { + if (!user) { throw new Meteor.Error('error-invalid-user', 'User not found'); } From 8db8187a63d2ba33c6e0d0dd9481c559a0ff81fc Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 23:25:30 +0530 Subject: [PATCH 17/22] Update misc.ts --- apps/meteor/app/api/server/v1/misc.ts | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index c81a7146e56e1..1ce3b9c3bc9ae 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -33,25 +33,8 @@ import { API } from '../api'; import { getPaginationItems } from '../helpers/getPaginationItems'; import { getUserFromParams } from '../helpers/getUserFromParams'; import { getUserInfo } from '../helpers/getUserInfo'; - -/** - * -------------------------------- - * Types and Schemas - * -------------------------------- - */ - -// Keys allowed in fields query -type Keys = - | 'name' | 'username' | 'nickname' | 'emails' | 'status' | 'statusDefault' - | 'statusText' | 'statusConnection' | 'bio' | 'avatarOrigin' | 'utcOffset' - | 'language' | 'settings' | 'idleTimeLimit' | 'roles' | 'active' | 'defaultRoom' - | 'customFields' | 'requirePasswordChange' | 'requirePasswordChangeReason' - | 'services.github' | 'services.gitlab' | 'services.password.bcrypt' - | 'services.totp.enabled' | 'services.email2fa.enabled' | 'statusLivechat' - | 'banners' | 'oauth.authorizedClients' | '_updatedAt' | 'avatarETag'; - -// Query params type -export type MeParams = { fields: Record | Record; user: IUser }; +import { ajv } from '@rocket.chat/rest-typings'; +import { MeParams } from '@rocket.chat/rest-typings'; // AJV validation schema const meSchema = { @@ -62,11 +45,6 @@ const meSchema = { }; export const isMeProps = ajv.compile(meSchema); -// Response type -export type IMeResponse = { - success: true; -} & Awaited>; - /** * -------------------------------- * /api/v1/me endpoint From c3285c77ae6301be5c67cb20133575c322599210 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 23:25:35 +0530 Subject: [PATCH 18/22] Update Ajv.ts --- packages/core-typings/src/Ajv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core-typings/src/Ajv.ts b/packages/core-typings/src/Ajv.ts index ec508fa1c35f5..14b5e60e18a07 100644 --- a/packages/core-typings/src/Ajv.ts +++ b/packages/core-typings/src/Ajv.ts @@ -11,7 +11,7 @@ import type { ISubscription } from './ISubscription'; import type { SlashCommand } from './SlashCommands'; import type { IMediaCall } from './mediaCalls/IMediaCall'; import type { IUser } from "./IUser"; -import type { IMeResponse } from '../../../apps/meteor/app/api/server/v1/misc'; +import type { IMeResponse } from '@rocket.chat/rest-typings'; export const schemas = typia.json.schemas< [ From fc4d7b1959a99ce691b4db77d213c490b1a47305 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 23:25:40 +0530 Subject: [PATCH 19/22] Create me.ts --- packages/rest-typings/src/v1/me.ts | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/rest-typings/src/v1/me.ts diff --git a/packages/rest-typings/src/v1/me.ts b/packages/rest-typings/src/v1/me.ts new file mode 100644 index 0000000000000..54928e2d3cbe7 --- /dev/null +++ b/packages/rest-typings/src/v1/me.ts @@ -0,0 +1,42 @@ +import type { IUser } from '@rocket.chat/core-typings'; + +type Keys = + | 'name' + | 'username' + | 'nickname' + | 'emails' + | 'status' + | 'statusDefault' + | 'statusText' + | 'statusConnection' + | 'bio' + | 'avatarOrigin' + | 'utcOffset' + | 'language' + | 'settings' + | 'idleTimeLimit' + | 'roles' + | 'active' + | 'defaultRoom' + | 'customFields' + | 'requirePasswordChange' + | 'requirePasswordChangeReason' + | 'services.github' + | 'services.gitlab' + | 'services.password.bcrypt' + | 'services.totp.enabled' + | 'services.email2fa.enabled' + | 'statusLivechat' + | 'banners' + | 'oauth.authorizedClients' + | '_updatedAt' + | 'avatarETag'; + +// Response type +export type IMeResponse = { + success: true; +}; + +export type MeParams = { + fields?: Partial>; +}; From 21e642c8f2d76d54cfc1febe3a0d9ad4bb556a17 Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 23:33:30 +0530 Subject: [PATCH 20/22] Update Ajv.ts --- packages/core-typings/src/Ajv.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core-typings/src/Ajv.ts b/packages/core-typings/src/Ajv.ts index 14b5e60e18a07..6383800bb7606 100644 --- a/packages/core-typings/src/Ajv.ts +++ b/packages/core-typings/src/Ajv.ts @@ -11,7 +11,6 @@ import type { ISubscription } from './ISubscription'; import type { SlashCommand } from './SlashCommands'; import type { IMediaCall } from './mediaCalls/IMediaCall'; import type { IUser } from "./IUser"; -import type { IMeResponse } from '@rocket.chat/rest-typings'; export const schemas = typia.json.schemas< [ @@ -20,7 +19,6 @@ export const schemas = typia.json.schemas< ICustomUserStatus, SlashCommand, IUser, - IMeResponse ], '3.0' >(); From 82858988ac1ab4904fa360f4a33e0835209f34ee Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Tue, 3 Mar 2026 23:41:36 +0530 Subject: [PATCH 21/22] Update me.ts --- packages/rest-typings/src/v1/me.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/rest-typings/src/v1/me.ts b/packages/rest-typings/src/v1/me.ts index 54928e2d3cbe7..9e91b742e85eb 100644 --- a/packages/rest-typings/src/v1/me.ts +++ b/packages/rest-typings/src/v1/me.ts @@ -1,6 +1,6 @@ import type { IUser } from '@rocket.chat/core-typings'; -type Keys = +export type Keys = | 'name' | 'username' | 'nickname' @@ -32,11 +32,10 @@ type Keys = | '_updatedAt' | 'avatarETag'; -// Response type -export type IMeResponse = { - success: true; -}; +export interface IMeResponse extends IUser { + success: true; +} -export type MeParams = { +export type MeParams = { fields?: Partial>; }; From 2cc3a4033cfe6be72d063aa7b5ecbbef2ea86bcc Mon Sep 17 00:00:00 2001 From: Yashika soni Date: Wed, 4 Mar 2026 00:16:07 +0530 Subject: [PATCH 22/22] Schema properties updates misc.ts --- apps/meteor/app/api/server/v1/misc.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/apps/meteor/app/api/server/v1/misc.ts b/apps/meteor/app/api/server/v1/misc.ts index 1ce3b9c3bc9ae..7279edd2e836c 100644 --- a/apps/meteor/app/api/server/v1/misc.ts +++ b/apps/meteor/app/api/server/v1/misc.ts @@ -38,10 +38,17 @@ import { MeParams } from '@rocket.chat/rest-typings'; // AJV validation schema const meSchema = { - type: 'object', - properties: {}, - additionalProperties: false, - required: ['fields', 'user'], + type: 'object', + properties: { + fields: { + type: 'object', + additionalProperties: { + type: 'integer', + enum: [0, 1], + }, + }, + }, + additionalProperties: false, }; export const isMeProps = ajv.compile(meSchema);