Skip to content

Commit 2f162a0

Browse files
feat: Add OpenAPI Support to oauth-apps.delete API (#36606)
1 parent 57c6a3a commit 2f162a0

File tree

5 files changed

+140
-144
lines changed

5 files changed

+140
-144
lines changed

.changeset/pink-games-shake.md

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

Lines changed: 134 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
ajv,
55
isUpdateOAuthAppParams,
66
isOauthAppsGetParams,
7-
isDeleteOAuthAppParams,
87
validateUnauthorizedErrorResponse,
98
validateBadRequestErrorResponse,
109
validateForbiddenErrorResponse,
@@ -18,50 +17,146 @@ import { updateOAuthApp } from '../../../oauth2-server-config/server/admin/metho
1817
import type { ExtractRoutesFromAPI } from '../ApiClass';
1918
import { API } from '../api';
2019

21-
const oauthAppsListEndpoints = API.v1.get(
22-
'oauth-apps.list',
23-
{
24-
authRequired: true,
25-
query: ajv.compile<{ uid?: string }>({
26-
type: 'object',
27-
properties: {
28-
uid: {
29-
type: 'string',
30-
},
31-
},
32-
additionalProperties: false,
33-
}),
34-
permissionsRequired: ['manage-oauth-apps'],
35-
response: {
36-
400: validateBadRequestErrorResponse,
37-
401: validateUnauthorizedErrorResponse,
38-
403: validateForbiddenErrorResponse,
39-
200: ajv.compile<{ oauthApps: IOAuthApps[] }>({
20+
type DeleteOAuthAppParams = {
21+
appId: string;
22+
};
23+
24+
const DeleteOAuthAppParamsSchema = {
25+
type: 'object',
26+
properties: {
27+
appId: {
28+
type: 'string',
29+
},
30+
},
31+
required: ['appId'],
32+
additionalProperties: false,
33+
};
34+
35+
const isDeleteOAuthAppParams = ajv.compile<DeleteOAuthAppParams>(DeleteOAuthAppParamsSchema);
36+
37+
export type OauthAppsAddParams = {
38+
name: string;
39+
active: boolean;
40+
redirectUri: string;
41+
};
42+
43+
const OauthAppsAddParamsSchema = {
44+
type: 'object',
45+
properties: {
46+
name: {
47+
type: 'string',
48+
},
49+
active: {
50+
type: 'boolean',
51+
},
52+
redirectUri: {
53+
type: 'string',
54+
},
55+
},
56+
required: ['name', 'active', 'redirectUri'],
57+
additionalProperties: false,
58+
};
59+
60+
const isOauthAppsAddParams = ajv.compile<OauthAppsAddParams>(OauthAppsAddParamsSchema);
61+
62+
const oauthAppsEndpoints = API.v1
63+
.get(
64+
'oauth-apps.list',
65+
{
66+
authRequired: true,
67+
query: ajv.compile<{ uid?: string }>({
4068
type: 'object',
4169
properties: {
42-
oauthApps: {
43-
type: 'array',
44-
items: {
45-
$ref: '#/components/schemas/IOAuthApps',
46-
},
47-
},
48-
success: {
49-
type: 'boolean',
50-
enum: [true],
70+
uid: {
71+
type: 'string',
5172
},
5273
},
53-
required: ['oauthApps', 'success'],
5474
additionalProperties: false,
5575
}),
76+
permissionsRequired: ['manage-oauth-apps'],
77+
response: {
78+
400: validateBadRequestErrorResponse,
79+
401: validateUnauthorizedErrorResponse,
80+
403: validateForbiddenErrorResponse,
81+
200: ajv.compile<{ oauthApps: IOAuthApps[] }>({
82+
type: 'object',
83+
properties: {
84+
oauthApps: {
85+
type: 'array',
86+
items: {
87+
$ref: '#/components/schemas/IOAuthApps',
88+
},
89+
},
90+
success: {
91+
type: 'boolean',
92+
enum: [true],
93+
},
94+
},
95+
required: ['oauthApps', 'success'],
96+
additionalProperties: false,
97+
}),
98+
},
5699
},
57-
},
58100

59-
async function action() {
60-
return API.v1.success({
61-
oauthApps: await OAuthApps.find().toArray(),
62-
});
63-
},
64-
);
101+
async function action() {
102+
return API.v1.success({
103+
oauthApps: await OAuthApps.find().toArray(),
104+
});
105+
},
106+
)
107+
.post(
108+
'oauth-apps.delete',
109+
{
110+
authRequired: true,
111+
body: isDeleteOAuthAppParams,
112+
permissionsRequired: ['manage-oauth-apps'],
113+
response: {
114+
400: validateBadRequestErrorResponse,
115+
401: validateUnauthorizedErrorResponse,
116+
403: validateForbiddenErrorResponse,
117+
200: ajv.compile<boolean>({ type: 'boolean' }),
118+
},
119+
},
120+
121+
async function action() {
122+
const { appId } = this.bodyParams;
123+
124+
const result = await deleteOAuthApp(this.userId, appId);
125+
126+
return API.v1.success(result);
127+
},
128+
)
129+
.post(
130+
'oauth-apps.create',
131+
{
132+
authRequired: true,
133+
body: isOauthAppsAddParams,
134+
permissionsRequired: ['manage-oauth-apps'],
135+
response: {
136+
400: validateBadRequestErrorResponse,
137+
401: validateUnauthorizedErrorResponse,
138+
403: validateForbiddenErrorResponse,
139+
200: ajv.compile<{ application: IOAuthApps }>({
140+
type: 'object',
141+
properties: {
142+
application: { $ref: '#/components/schemas/IOAuthApps' },
143+
success: {
144+
type: 'boolean',
145+
enum: [true],
146+
},
147+
},
148+
required: ['application', 'success'],
149+
additionalProperties: false,
150+
}),
151+
},
152+
},
153+
154+
async function action() {
155+
const application = await addOAuthApp(this.bodyParams, this.userId);
156+
157+
return API.v1.success({ application });
158+
},
159+
);
65160

66161
API.v1.addRoute(
67162
'oauth-apps.get',
@@ -108,90 +203,9 @@ API.v1.addRoute(
108203
},
109204
);
110205

111-
API.v1.addRoute(
112-
'oauth-apps.delete',
113-
{
114-
authRequired: true,
115-
validateParams: isDeleteOAuthAppParams,
116-
permissionsRequired: ['manage-oauth-apps'],
117-
},
118-
{
119-
async post() {
120-
const { appId } = this.bodyParams;
121-
122-
const result = await deleteOAuthApp(this.userId, appId);
123-
124-
return API.v1.success(result);
125-
},
126-
},
127-
);
128-
129-
export type OauthAppsAddParams = {
130-
name: string;
131-
active: boolean;
132-
redirectUri: string;
133-
};
134-
135-
const OauthAppsAddParamsSchema = {
136-
type: 'object',
137-
properties: {
138-
name: {
139-
type: 'string',
140-
},
141-
active: {
142-
type: 'boolean',
143-
},
144-
redirectUri: {
145-
type: 'string',
146-
},
147-
},
148-
required: ['name', 'active', 'redirectUri'],
149-
additionalProperties: false,
150-
};
151-
152-
const isOauthAppsAddParams = ajv.compile<OauthAppsAddParams>(OauthAppsAddParamsSchema);
153-
154-
const oauthAppsCreateEndpoints = API.v1.post(
155-
'oauth-apps.create',
156-
{
157-
authRequired: true,
158-
body: isOauthAppsAddParams,
159-
permissionsRequired: ['manage-oauth-apps'],
160-
response: {
161-
400: validateBadRequestErrorResponse,
162-
401: validateUnauthorizedErrorResponse,
163-
403: validateForbiddenErrorResponse,
164-
200: ajv.compile<{ application: IOAuthApps }>({
165-
type: 'object',
166-
properties: {
167-
application: { $ref: '#/components/schemas/IOAuthApps' },
168-
success: {
169-
type: 'boolean',
170-
enum: [true],
171-
},
172-
},
173-
required: ['application', 'success'],
174-
additionalProperties: false,
175-
}),
176-
},
177-
},
178-
179-
async function action() {
180-
const application = await addOAuthApp(this.bodyParams, this.userId);
181-
182-
return API.v1.success({ application });
183-
},
184-
);
185-
186-
type OauthAppsCreateEndpoints = ExtractRoutesFromAPI<typeof oauthAppsCreateEndpoints>;
187-
188-
type OauthAppsListEndpoints = ExtractRoutesFromAPI<typeof oauthAppsListEndpoints>;
189-
190-
export type OAuthAppsEndpoints = OauthAppsCreateEndpoints | OauthAppsListEndpoints;
206+
export type OauthAppsEndpoints = ExtractRoutesFromAPI<typeof oauthAppsEndpoints>;
191207

192208
declare module '@rocket.chat/rest-typings' {
193209
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
194-
interface Endpoints extends OauthAppsCreateEndpoints {}
195-
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-empty-interface
196-
interface Endpoints extends OauthAppsListEndpoints {}
210+
interface Endpoints extends OauthAppsEndpoints {}
197211
}

packages/rest-typings/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,6 @@ export * from './v1/omnichannel';
237237
export * from './v1/oauthapps';
238238
export * from './v1/oauthapps/UpdateOAuthAppParamsPOST';
239239
export * from './v1/oauthapps/OAuthAppsGetParamsGET';
240-
export * from './v1/oauthapps/DeleteOAuthAppParamsDELETE';
241240
export * from './helpers/PaginatedRequest';
242241
export * from './helpers/PaginatedResult';
243242
export * from './helpers/ReplacePlaceholders';

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { IOAuthApps } from '@rocket.chat/core-typings';
22

3-
import type { DeleteOAuthAppParams } from './oauthapps/DeleteOAuthAppParamsDELETE';
43
import type { OauthAppsGetParams } from './oauthapps/OAuthAppsGetParamsGET';
54
import type { UpdateOAuthAppParams } from './oauthapps/UpdateOAuthAppParamsPOST';
65

@@ -14,8 +13,4 @@ export type OAuthAppsEndpoint = {
1413
'/v1/oauth-apps.update': {
1514
POST: (params: UpdateOAuthAppParams) => IOAuthApps | null;
1615
};
17-
18-
'/v1/oauth-apps.delete': {
19-
POST: (params: DeleteOAuthAppParams) => boolean;
20-
};
2116
};

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

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

0 commit comments

Comments
 (0)