Skip to content

Commit 17bca96

Browse files
ahmed-n-abdeltwabcardosoggazzo
authored
feat: Add OpenAPI Support to oauth-apps.get API (RocketChat#36598)
Co-authored-by: Matheus Cardoso <matheus@cardo.so> Co-authored-by: Guilherme Gazzo <guilherme@gazzo.xyz>
1 parent 68499d4 commit 17bca96

8 files changed

Lines changed: 80 additions & 68 deletions

File tree

.changeset/tall-scissors-boil.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@rocket.chat/meteor": patch
3+
"@rocket.chat/core-typings": patch
4+
"@rocket.chat/rest-typings": patch
5+
---
6+
7+
Add OpenAPI support for the Rocket.Chat oauth-apps.get 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.

apps/meteor/app/api/server/definition.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,8 @@ export type TypedThis<TOptions extends TypedOptions, TPath extends string = ''>
303303
bodyParams: TOptions['body'] extends ValidateFunction<infer Body> ? Body : never;
304304

305305
requestIp?: string;
306+
route: string;
307+
response: Response;
306308
};
307309

308310
type PromiseOrValue<T> = T | Promise<T>;

apps/meteor/app/api/server/v1/oauthapps.ts

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type { IOAuthApps } from '@rocket.chat/core-typings';
22
import { OAuthApps } from '@rocket.chat/models';
33
import {
44
ajv,
5-
isOauthAppsGetParams,
65
validateUnauthorizedErrorResponse,
76
validateBadRequestErrorResponse,
87
validateForbiddenErrorResponse,
@@ -89,6 +88,45 @@ const UpdateOAuthAppParamsSchema = {
8988

9089
const isUpdateOAuthAppParams = ajv.compile<UpdateOAuthAppParams>(UpdateOAuthAppParamsSchema);
9190

91+
type OauthAppsGetParams = { clientId: string } | { appId: string } | { _id: string };
92+
93+
const oauthAppsGetParamsSchema = {
94+
oneOf: [
95+
{
96+
type: 'object',
97+
properties: {
98+
_id: {
99+
type: 'string',
100+
},
101+
},
102+
required: ['_id'],
103+
additionalProperties: false,
104+
},
105+
{
106+
type: 'object',
107+
properties: {
108+
clientId: {
109+
type: 'string',
110+
},
111+
},
112+
required: ['clientId'],
113+
additionalProperties: false,
114+
},
115+
{
116+
type: 'object',
117+
properties: {
118+
appId: {
119+
type: 'string',
120+
},
121+
},
122+
required: ['appId'],
123+
additionalProperties: false,
124+
},
125+
],
126+
};
127+
128+
const isOauthAppsGetParams = ajv.compile<OauthAppsGetParams>(oauthAppsGetParamsSchema);
129+
92130
const oauthAppsEndpoints = API.v1
93131
.get(
94132
'oauth-apps.list',
@@ -218,13 +256,31 @@ const oauthAppsEndpoints = API.v1
218256

219257
return API.v1.success(result);
220258
},
221-
);
259+
)
260+
.get(
261+
'oauth-apps.get',
262+
{
263+
authRequired: true,
264+
query: isOauthAppsGetParams,
265+
response: {
266+
400: validateBadRequestErrorResponse,
267+
401: validateUnauthorizedErrorResponse,
268+
200: ajv.compile<{ oauthApp: IOAuthApps }>({
269+
type: 'object',
270+
properties: {
271+
oauthApp: { anyOf: [{ $ref: '#/components/schemas/IOAuthApps' }, { type: 'null' }] },
272+
success: {
273+
type: 'boolean',
274+
enum: [true],
275+
},
276+
},
277+
required: ['oauthApp', 'success'],
278+
additionalProperties: false,
279+
}),
280+
},
281+
},
222282

223-
API.v1.addRoute(
224-
'oauth-apps.get',
225-
{ authRequired: true, validateParams: isOauthAppsGetParams },
226-
{
227-
async get() {
283+
async function action() {
228284
const isOAuthAppsManager = await hasPermissionAsync(this.userId, 'manage-oauth-apps');
229285

230286
const oauthApp = await OAuthApps.findOneAuthAppByIdOrClientId(
@@ -244,8 +300,7 @@ API.v1.addRoute(
244300
oauthApp,
245301
});
246302
},
247-
},
248-
);
303+
);
249304

250305
export type OauthAppsEndpoints = ExtractRoutesFromAPI<typeof oauthAppsEndpoints>;
251306

apps/meteor/tests/end-to-end/api/oauthapps.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,9 @@ describe('[OAuthApps]', () => {
286286
.expect(400)
287287
.expect((res) => {
288288
expect(res.body).to.have.property('success', false);
289+
expect(res.body).to.have.property('errorType', 'error-invalid-params');
289290
expect(res.body).to.have.property('error');
290-
expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf [invalid-params]');
291+
expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf');
291292
});
292293
});
293294

@@ -311,8 +312,9 @@ describe('[OAuthApps]', () => {
311312
.expect(400)
312313
.expect((res) => {
313314
expect(res.body).to.have.property('success', false);
315+
expect(res.body).to.have.property('errorType', 'error-invalid-params');
314316
expect(res.body).to.have.property('error');
315-
expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf [invalid-params]');
317+
expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf');
316318
});
317319
});
318320

@@ -336,8 +338,9 @@ describe('[OAuthApps]', () => {
336338
.expect(400)
337339
.expect((res) => {
338340
expect(res.body).to.have.property('success', false);
341+
expect(res.body).to.have.property('errorType', 'error-invalid-params');
339342
expect(res.body).to.have.property('error');
340-
expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf [invalid-params]');
343+
expect(res.body.error).to.include('must be string').and.include('must match exactly one schema in oneOf');
341344
});
342345
});
343346

packages/core-typings/src/IOAuthApps.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export interface IOAuthApps {
33
name: string;
44
active: boolean;
55
clientId: string;
6-
clientSecret: string;
6+
clientSecret?: string;
77
redirectUri: string;
88
_createdAt: Date;
99
_createdBy: {

packages/rest-typings/src/index.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import type { MailerEndpoints } from './v1/mailer';
3333
import type { MeEndpoints } from './v1/me';
3434
import type { MiscEndpoints } from './v1/misc';
3535
import type { ModerationEndpoints } from './v1/moderation';
36-
import type { OAuthAppsEndpoint } from './v1/oauthapps';
3736
import type { OmnichannelEndpoints } from './v1/omnichannel';
3837
import type { PresenceEndpoints } from './v1/presence';
3938
import type { PushEndpoints } from './v1/push';
@@ -89,7 +88,6 @@ export interface Endpoints
8988
AssetsEndpoints,
9089
EmailInboxEndpoints,
9190
MailerEndpoints,
92-
OAuthAppsEndpoint,
9391
SubscriptionsEndpoints,
9492
AutoTranslateEndpoints,
9593
ImportEndpoints,
@@ -231,8 +229,6 @@ export * from './v1/dm/DmHistoryProps';
231229
export * from './v1/integrations';
232230
export * from './v1/licenses';
233231
export * from './v1/omnichannel';
234-
export * from './v1/oauthapps';
235-
export * from './v1/oauthapps/OAuthAppsGetParamsGET';
236232
export * from './helpers/PaginatedRequest';
237233
export * from './helpers/PaginatedResult';
238234
export * from './helpers/ReplacePlaceholders';

packages/rest-typings/src/v1/oauthapps.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

packages/rest-typings/src/v1/oauthapps/OAuthAppsGetParamsGET.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)