diff --git a/.changeset/strange-worms-smoke.md b/.changeset/strange-worms-smoke.md new file mode 100644 index 00000000000..a0bb1db1030 --- /dev/null +++ b/.changeset/strange-worms-smoke.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/rest-typings": patch +--- + +Add OpenAPI support for the Rocket.Chat oauth-apps.list API 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. diff --git a/apps/meteor/app/api/server/v1/oauthapps.ts b/apps/meteor/app/api/server/v1/oauthapps.ts index d154b25ea57..9a9798751a3 100644 --- a/apps/meteor/app/api/server/v1/oauthapps.ts +++ b/apps/meteor/app/api/server/v1/oauthapps.ts @@ -18,16 +18,49 @@ import { updateOAuthApp } from '../../../oauth2-server-config/server/admin/metho import type { ExtractRoutesFromAPI } from '../ApiClass'; import { API } from '../api'; -API.v1.addRoute( +const oauthAppsListEndpoints = API.v1.get( 'oauth-apps.list', - { authRequired: true, permissionsRequired: ['manage-oauth-apps'] }, { - async get() { - return API.v1.success({ - oauthApps: await OAuthApps.find().toArray(), - }); + authRequired: true, + query: ajv.compile<{ uid?: string }>({ + type: 'object', + properties: { + uid: { + type: 'string', + }, + }, + additionalProperties: false, + }), + permissionsRequired: ['manage-oauth-apps'], + response: { + 400: validateBadRequestErrorResponse, + 401: validateUnauthorizedErrorResponse, + 403: validateForbiddenErrorResponse, + 200: ajv.compile<{ oauthApps: IOAuthApps[] }>({ + type: 'object', + properties: { + oauthApps: { + type: 'array', + items: { + $ref: '#/components/schemas/IOAuthApps', + }, + }, + success: { + type: 'boolean', + enum: [true], + }, + }, + required: ['oauthApps', 'success'], + additionalProperties: false, + }), }, }, + + async function action() { + return API.v1.success({ + oauthApps: await OAuthApps.find().toArray(), + }); + }, ); API.v1.addRoute( @@ -152,9 +185,13 @@ const oauthAppsCreateEndpoints = API.v1.post( type OauthAppsCreateEndpoints = ExtractRoutesFromAPI; -export type OAuthAppsEndpoints = OauthAppsCreateEndpoints; +type OauthAppsListEndpoints = ExtractRoutesFromAPI; + +export type OAuthAppsEndpoints = OauthAppsCreateEndpoints | OauthAppsListEndpoints; declare module '@rocket.chat/rest-typings' { // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface interface Endpoints extends OauthAppsCreateEndpoints {} + // eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface + interface Endpoints extends OauthAppsListEndpoints {} } diff --git a/packages/rest-typings/src/v1/oauthapps.ts b/packages/rest-typings/src/v1/oauthapps.ts index 2e42cf12c87..c463c08acdd 100644 --- a/packages/rest-typings/src/v1/oauthapps.ts +++ b/packages/rest-typings/src/v1/oauthapps.ts @@ -1,16 +1,10 @@ -import type { IOAuthApps, IUser } from '@rocket.chat/core-typings'; +import type { IOAuthApps } from '@rocket.chat/core-typings'; import type { DeleteOAuthAppParams } from './oauthapps/DeleteOAuthAppParamsDELETE'; import type { OauthAppsGetParams } from './oauthapps/OAuthAppsGetParamsGET'; import type { UpdateOAuthAppParams } from './oauthapps/UpdateOAuthAppParamsPOST'; export type OAuthAppsEndpoint = { - '/v1/oauth-apps.list': { - GET: (params: { uid: IUser['_id'] }) => { - oauthApps: IOAuthApps[]; - }; - }; - '/v1/oauth-apps.get': { GET: (params: OauthAppsGetParams) => { oauthApp: IOAuthApps;