diff --git a/.changeset/migrate-roles-list-openapi.md b/.changeset/migrate-roles-list-openapi.md new file mode 100644 index 0000000000000..a9a84f667ffc0 --- /dev/null +++ b/.changeset/migrate-roles-list-openapi.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/rest-typings": patch +--- + +Migrates the `roles.list` 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. diff --git a/apps/meteor/app/api/server/v1/roles.ts b/apps/meteor/app/api/server/v1/roles.ts index 8985e48c0aff5..d9bc46e5fd14b 100644 --- a/apps/meteor/app/api/server/v1/roles.ts +++ b/apps/meteor/app/api/server/v1/roles.ts @@ -1,7 +1,13 @@ import { api, Authorization } from '@rocket.chat/core-services'; import type { IRole } from '@rocket.chat/core-typings'; import { Roles, Users } from '@rocket.chat/models'; -import { ajv, isRoleAddUserToRoleProps, isRoleDeleteProps, isRoleRemoveUserFromRoleProps } from '@rocket.chat/rest-typings'; +import { + ajv, + isRoleAddUserToRoleProps, + isRoleDeleteProps, + isRoleRemoveUserFromRoleProps, + validateUnauthorizedErrorResponse, +} from '@rocket.chat/rest-typings'; import { check, Match } from 'meteor/check'; import { Meteor } from 'meteor/meteor'; @@ -17,18 +23,6 @@ import { API } from '../api'; import { getPaginationItems } from '../helpers/getPaginationItems'; import { getUserFromParams } from '../helpers/getUserFromParams'; -API.v1.addRoute( - 'roles.list', - { authRequired: true }, - { - async get() { - const roles = await Roles.find({}, { projection: { _updatedAt: 0 } }).toArray(); - - return API.v1.success({ roles }); - }, - }, -); - API.v1.addRoute( 'roles.sync', { authRequired: true }, @@ -225,38 +219,82 @@ API.v1.addRoute( }, ); -const rolesRoutes = API.v1.get( - 'roles.getUsersInPublicRoles', - { - authRequired: true, - response: { - 200: ajv.compile<{ - users: { - _id: string; - username: string; - roles: string[]; - }[]; - }>({ - type: 'object', - properties: { - users: { - type: 'array', - items: { - type: 'object', - properties: { _id: { type: 'string' }, username: { type: 'string' }, roles: { type: 'array', items: { type: 'string' } } }, +const rolesRoutes = API.v1 + .get( + 'roles.list', + { + authRequired: true, + response: { + 200: ajv.compile<{ + roles: IRole[]; + }>({ + type: 'object', + properties: { + roles: { + type: 'array', + items: { + $ref: '#/components/schemas/IRole', + }, + }, + success: { + type: 'boolean', + enum: [true], }, }, - }, - }), + required: ['roles', 'success'], + additionalProperties: false, + }), + 401: validateUnauthorizedErrorResponse, + }, }, - }, + async function action() { + const roles = await Roles.find({}, { projection: { _updatedAt: 0 } }).toArray(); - async () => { - return API.v1.success({ - users: await Authorization.getUsersFromPublicRoles(), - }); - }, -); + return API.v1.success({ roles }); + }, + ) + .get( + 'roles.getUsersInPublicRoles', + { + authRequired: true, + response: { + 200: ajv.compile<{ + users: { + _id: string; + username: string; + roles: string[]; + }[]; + }>({ + type: 'object', + properties: { + users: { + type: 'array', + items: { + type: 'object', + properties: { + _id: { type: 'string' }, + username: { type: 'string' }, + roles: { type: 'array', items: { type: 'string' } }, + }, + }, + }, + success: { + type: 'boolean', + enum: [true], + }, + }, + required: ['users', 'success'], + additionalProperties: false, + }), + 401: validateUnauthorizedErrorResponse, + }, + }, + async function action() { + return API.v1.success({ + users: await Authorization.getUsersFromPublicRoles(), + }); + }, + ); type RolesEndpoints = ExtractRoutesFromAPI; diff --git a/packages/rest-typings/src/v1/roles.ts b/packages/rest-typings/src/v1/roles.ts index 93845a150cecd..de2c4f17aaa55 100644 --- a/packages/rest-typings/src/v1/roles.ts +++ b/packages/rest-typings/src/v1/roles.ts @@ -118,11 +118,6 @@ type RoleSyncProps = { }; export type RolesEndpoints = { - '/v1/roles.list': { - GET: () => { - roles: IRole[]; - }; - }; '/v1/roles.sync': { GET: (params: RoleSyncProps) => { roles: {